How to Use OCR to Make PDF Image Text Searchable with Java
This step-by-step tutorial explains how a Java application can use OCR to make PDF image text searchable through the OCR PDF API Tool. The Java request submits an image-based PDF to /pdf-with-ocr-text and receives a searchable PDF resource for later search and text selection. After reviewing the example, you'll be ready to use OCR to make PDF image text searchable with your own input.
Why Use OCR to Make PDF Image Text Searchable with Java?
A records portal may display scanned pages correctly while users still cannot search or select their text. OCR adds recognized text without requiring the application to recreate the document.
The Java sample sends the PDF to /pdf-with-ocr-text. OCR language and related options should match the source material for the best recognition results.
Java Code Example
import io.github.cdimascio.dotenv.Dotenv;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONObject;
public class PDFWithOCRText {
// By default, we use the US-based API service. This is the primary endpoint for global use.
private static final String API_URL = "https://api.pdfrest.com";
// For GDPR compliance and enhanced performance for European users, you can switch to the EU-based
// service by commenting out the URL above and uncommenting the URL below.
// For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
// private static final String API_URL = "https://eu-api.pdfrest.com";
// Specify the path to your file here, or as the first argument when running the program.
private static final String DEFAULT_FILE_PATH = "/path/to/file.pdf";
// Specify your API key here, or in the environment variable PDFREST_API_KEY.
// You can also put the environment variable in a .env file.
private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static void main(String[] args) {
File inputFile;
if (args.length > 0) {
inputFile = new File(args[0]);
} else {
inputFile = new File(DEFAULT_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody inputFileRequestBody =
RequestBody.create(inputFile, MediaType.parse("application/pdf"));
RequestBody requestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", inputFile.getName(), inputFileRequestBody)
.addFormDataPart("output", "pdfrest_pdf-with-ocr-text")
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(requestBody)
.build();
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response response = client.newCall(request).execute();
System.out.println("Result code " + response.code());
if (response.body() != null) {
System.out.println(prettyJson(response.body().string()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static String prettyJson(String json) {
// https://stackoverflow.com/a/9583835/11996393
return new JSONObject(json).toString(4);
}
}
Source: Java sample on GitHub.
Breaking Down the Code
Load the Java HTTP and JSON dependencies
import io.github.cdimascio.dotenv.Dotenv; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import org.json.JSONObject;
The sample relies on OkHttp to send the call, dotenv to resolve credentials, and org.json to inspect or format JSON.
Choose the input and load credentials
// service by commenting out the URL above and uncommenting the URL below.
// For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
// private static final String API_URL = "https://eu-api.pdfrest.com";
// Specify the path to your file here, or as the first argument when running the program.
private static final String DEFAULT_FILE_PATH = "/path/to/file.pdf";
// Specify your API key here, or in the environment variable PDFREST_API_KEY.
// You can also put the environment variable in a .env file.
private static final String DEFAULT_API_KEY = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static void main(String[] args) {
File inputFile;
if (args.length > 0) {
inputFile = new File(args[0]);
} else {
inputFile = new File(DEFAULT_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody inputFileRequestBody =
The configuration block shows where the input comes from and keeps the credential outside the request-building logic.
Build the multipart request body
final RequestBody inputFileRequestBody =
RequestBody.create(inputFile, MediaType.parse("application/pdf"));
RequestBody requestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", inputFile.getName(), inputFileRequestBody)
.addFormDataPart("output", "pdfrest_pdf-with-ocr-text")
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(requestBody)
.build();
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
The Java sample sends the PDF to /pdf-with-ocr-text. OCR language and related options should match the source material for the best recognition results. The form-data setup sets MultipartBody.FORM, allowing OkHttp to generate the matching boundary automatically.
Send the request to pdfRest
.build();
Request request =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(requestBody)
.build();
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response response = client.newCall(request).execute();
The client request joins authentication, routing, and payload in one place while leaving regional service selection in the API URL constant.
Read the API response
try {
OkHttpClient client =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response response = client.newCall(request).execute();
System.out.println("Result code " + response.code());
if (response.body() != null) {
System.out.println(prettyJson(response.body().string()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static String prettyJson(String json) {
// https://stackoverflow.com/a/9583835/11996393
return new JSONObject(json).toString(4);
The response check makes success and failure information available to the caller, including any temporary resources that must be saved or reused before expiration.
Beyond the Tutorial
The completed example gives you a practical Java starting point for learning how to use OCR to make PDF image text searchable. With that foundation, searchable OCR PDFs improve retrieval, review, copy-and-paste, and downstream text-processing workflows.
As you apply the pattern to real documents, choose OCR language settings that match the source and review low-quality scans for recognition errors. A searchable text layer improves discovery and selection, but it does not by itself establish accessibility conformance or correct the logical reading structure of the PDF.
Before integrating this workflow, test representative documents with the Use OCR to Make PDF Image Text Searchable operation in API Lab. Then use the OCR PDF API Tool documentation to review every available parameter and response field.
Note: The Use OCR to Make PDF Image Text Searchable example above uses multipart form data; to reuse a resource ID, see the request shape in the JSON payload example.