Java SDK
Official Java SDK for TruthMark invisible watermarking.
Installation
Maven
<dependency>
<groupId>com.truthmark</groupId>
<artifactId>truthmark-sdk</artifactId>
<version>1.0.0</version>
</dependency>Gradle
implementation 'com.truthmark:truthmark-sdk:1.0.0'Quick Example
import com.truthmark.sdk.TruthMarkClient;
import com.truthmark.sdk.TruthMarkClient.EncodeResult;
import com.truthmark.sdk.TruthMarkClient.DecodeResult;
public class Example {
public static void main(String[] args) {
TruthMarkClient client = new TruthMarkClient.Builder()
.apiKey("tm_live_your_key")
.baseUrl("https://truthmark-api.onrender.com")
.build();
try {
// Encode
EncodeResult result = client.encode("image.png", "Copyright 2025");
System.out.println("Download: " + result.getDownloadUrl());
System.out.printf("PSNR: %.1f dB%n", result.getMetadata().getPsnr());
// Decode
DecodeResult decoded = client.decode("watermarked.png");
if (decoded.isFound()) {
System.out.println("Message: " + decoded.getMessage());
System.out.printf("Confidence: %.1f%%%n", decoded.getConfidence() * 100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}API Reference
TruthMarkClient.Builder
Configure and create a client instance.
.apiKey(String)— Your TruthMark API key.baseUrl(String)— API base URL.timeout(int)— Request timeout in ms.build()— Create the client
encode(String imagePath, String message)
Embed an invisible watermark. Returns EncodeResult.
decode(String imagePath)
Extract watermark. Returns DecodeResult.
Error Handling
import com.truthmark.sdk.TruthMarkException;
try {
EncodeResult result = client.encode("image.png", "message");
} catch (TruthMarkException e) {
switch (e.getStatusCode()) {
case 401 -> System.err.println("Invalid API key");
case 429 -> System.err.println("Rate limited. Retry after: " + e.getRetryAfter());
case 413 -> System.err.println("Image too large (max 20MB)");
default -> System.err.println("Error: " + e.getMessage());
}
}Advanced Examples
Spring Boot Service
@Service
public class WatermarkService {
private final TruthMarkClient client;
public WatermarkService(@Value("${truthmark.api-key}") String apiKey) {
this.client = new TruthMarkClient.Builder()
.apiKey(apiKey)
.build();
}
public EncodeResult watermark(MultipartFile file, String message) throws Exception {
Path temp = Files.createTempFile("upload", ".png");
file.transferTo(temp);
try {
return client.encode(temp.toString(), message);
} finally {
Files.deleteIfExists(temp);
}
}
}Batch Processing with Streams
Path dir = Path.of("./images");
List<EncodeResult> results = Files.list(dir)
.filter(p -> p.toString().matches(".*\\.(png|jpg|jpeg)$"))
.parallel()
.map(p -> {
try {
return client.encode(p.toString(), "© 2025 My Company");
} catch (Exception e) {
System.err.println("Failed: " + p + " - " + e.getMessage());
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
System.out.printf("Watermarked %d images%n", results.size());Best Practices
Reuse client instances
Create one TruthMarkClient per application — it's thread-safe.
Use environment variables
Store API keys in application.properties or env vars, never hardcode.
Don't ignore exceptions
Always handle TruthMarkException — check status codes for retryable errors.