How to Use OCR to Extract Text from PDF Images with Java
In the following tutorial, you'll use Java and the OCR PDF API Tool to use OCR to extract text from PDF images. The complex flow passes the OCR output ID directly into Extract Text, avoiding a download and re-upload between operations. The example is designed to clarify both the API-specific fields and the surrounding HTTP request used to use OCR to extract text from PDF images.
Why Use OCR to Extract Text from PDF Images with Java?
A scanned document may contain visible words but no searchable text objects. The two-step workflow first adds an OCR text layer and then extracts that recognized content for indexing or analysis.
The Complex Flow example passes the OCR call’s outputId into /extracted-text. This resource-ID handoff avoids downloading and uploading the intermediate PDF.
Java Code Example
import io.github.cdimascio.dotenv.Dotenv;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.*;
import org.json.JSONObject;
/* In this sample, we will show how to convert a scanned document into a PDF with
* searchable and extractable text using Optical Character Recognition (OCR), and then
* extract that text from the newly created document.
*
* First, we will upload a scanned PDF to the /pdf-with-ocr-text route and capture the
* output ID. Then, we will send the output ID to the /extracted-text route, which will
* return the newly added text.
*/
public class OcrWithExtractText {
// 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 PDF file here, or as the first argument when running the program.
private static final String DEFAULT_PDF_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 pdfFile;
if (args.length > 0) {
pdfFile = new File(args[0]);
} else {
pdfFile = new File(DEFAULT_PDF_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody pdfFileRequestBody =
RequestBody.create(pdfFile, MediaType.parse("application/pdf"));
RequestBody ocrRequestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", pdfFile.getName(), pdfFileRequestBody)
.addFormDataPart("output", "example_pdf-with-ocr-text_out")
.build();
Request ocrRequest =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(ocrRequestBody)
.build();
try {
OkHttpClient ocrClient =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response ocrResponse = ocrClient.newCall(ocrRequest).execute();
System.out.println("Response status code: " + ocrResponse.code());
if (ocrResponse.body() != null) {
String ocrResponseString = ocrResponse.body().string();
JSONObject ocrJSON = new JSONObject(ocrResponseString);
if (ocrJSON.has("error")) {
System.out.println("Error during OCR call: " + ocrResponseString);
return;
}
String ocrPDFID = ocrJSON.get("outputId").toString();
System.out.println("Got the output ID: " + ocrPDFID);
RequestBody extractRequestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("id", ocrPDFID)
.build();
Request extractRequest =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/extracted-text")
.post(extractRequestBody)
.build();
try {
OkHttpClient extractClient =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response extractResponse = extractClient.newCall(extractRequest).execute();
System.out.println("Response status code: " + extractResponse.code());
if (extractResponse.body() != null) {
String extractResponseString = extractResponse.body().string();
JSONObject extractJSON = new JSONObject(extractResponseString);
if (extractJSON.has("error")) {
System.out.println("Error during text extraction call: " + extractResponseString);
return;
}
System.out.println(extractJSON.getString("fullText"));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
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.*; import org.json.JSONObject;
This client combines OkHttp networking with dotenv configuration and org.json processing.
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 PDF file here, or as the first argument when running the program.
private static final String DEFAULT_PDF_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 pdfFile;
if (args.length > 0) {
pdfFile = new File(args[0]);
} else {
pdfFile = new File(DEFAULT_PDF_FILE_PATH);
}
final Dotenv dotenv = Dotenv.configure().ignoreIfMalformed().ignoreIfMissing().load();
final RequestBody pdfFileRequestBody =
The sample configuration separates file selection from authentication so either value can change without rewriting the request.
Build the multipart request body
final RequestBody pdfFileRequestBody =
RequestBody.create(pdfFile, MediaType.parse("application/pdf"));
RequestBody ocrRequestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", pdfFile.getName(), pdfFileRequestBody)
.addFormDataPart("output", "example_pdf-with-ocr-text_out")
.build();
Request ocrRequest =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(ocrRequestBody)
.build();
try {
OkHttpClient ocrClient =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
The Complex Flow example passes the OCR call’s outputId into /extracted-text. This resource-ID handoff avoids downloading and uploading the intermediate PDF. This request body collects the named parts before OkHttp calculates the final multipart header and body encoding.
Send the request to pdfRest
.build();
Request ocrRequest =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
.url(API_URL + "/pdf-with-ocr-text")
.post(ocrRequestBody)
.build();
try {
OkHttpClient ocrClient =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
The HTTP request adds the API key header, selects the operation URL, and attaches the prepared body; changing the base constant switches between US and EU service hosts.
Pass resources between workflow stages
if (ocrJSON.has("error")) {
System.out.println("Error during OCR call: " + ocrResponseString);
return;
}
String ocrPDFID = ocrJSON.get("outputId").toString();
System.out.println("Got the output ID: " + ocrPDFID);
RequestBody extractRequestBody =
new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("id", ocrPDFID)
.build();
Request extractRequest =
new Request.Builder()
.header("Api-Key", dotenv.get("PDFREST_API_KEY", DEFAULT_API_KEY))
In the Use OCR to Extract Text from PDF Images workflow, Java reads the generated resource ID from one response and supplies it to the next endpoint, avoiding a download and another upload of the intermediate file.
Read the API response
OkHttpClient ocrClient =
new OkHttpClient().newBuilder().readTimeout(60, TimeUnit.SECONDS).build();
Response ocrResponse = ocrClient.newCall(ocrRequest).execute();
System.out.println("Response status code: " + ocrResponse.code());
if (ocrResponse.body() != null) {
String ocrResponseString = ocrResponse.body().string();
JSONObject ocrJSON = new JSONObject(ocrResponseString);
if (ocrJSON.has("error")) {
System.out.println("Error during OCR call: " + ocrResponseString);
return;
}
String ocrPDFID = ocrJSON.get("outputId").toString();
The first response supplies the OCR PDF resource ID, while the second returns the recognized text; the example checks both stages for errors before printing fullText.
Beyond the Tutorial
We have now covered the request and response flow for using Java to use OCR to extract text from PDF images. With that foundation, you can use OCR plus extraction for scanned correspondence, historical records, receipts, and image-based document archives.
Before relying on the result in an automated workflow, keep in mind that recognition quality depends on scan resolution, orientation, language, and image clarity, so test the actual document population. Preserve both the searchable PDF ID and extracted text when later steps need visual verification of what OCR recognized.
Continue testing representative documents with the Use OCR to Extract Text from PDF Images operation in API Lab. The OCR PDF API Tool documentation provides authoritative defaults, accepted fields, and limitations for the Use OCR to Extract Text from PDF Images operation.