Skip to main content
Version: v3000

Scan a card from a static image

For file upload or gallery flows, use the lower-level scanning session directly, without the camera UI. This lets you feed images into the scanning engine one at a time.

Initialize and create a session​

Create a session with the input image source set to photo. This tells the engine to expect static images rather than a video stream.

On Web, load the core engine with loadBlinkCardCore, then create the session. On Android, initialize the SDK, then create the session. On iOS, create the SDK, then create the session.

import { loadBlinkCardCore } from "@microblink/blinkcard-core";

const blinkCardCore = await loadBlinkCardCore({
licenseKey: "your-license-key",
});

const session = await blinkCardCore.createScanningSession({
inputImageSource: "photo",
});

For installation, license setup, and hosting the WASM resources, see the quickstart.

Load an image for scanning​

Each platform wraps a decoded image in the format the scanning engine expects.

On Web, the engine accepts ImageData. Use an offscreen canvas to decode a File or Blob into the required format.

On Android, build an InputImage from an ARGB_8888 Bitmap loaded from the gallery or a file.

On iOS, build an InputImage from a UIImage loaded from the photo library or a file.

async function fileToImageData(file: File): Promise<ImageData> {
const img = new Image();
const url = URL.createObjectURL(file);
img.src = url;

try {
await new Promise<void>((resolve) => {
img.onload = () => resolve();
});
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("Could not get canvas context");
ctx.drawImage(img, 0, 0);
return ctx.getImageData(0, 0, canvas.width, canvas.height);
} finally {
URL.revokeObjectURL(url);
}
}

Process images and get the result​

Pass each image to the session and check the processing status after each call. A status of awaiting-other-side means the engine needs the card's other side before it can return a final result. When the card is fully scanned, retrieve the result with getResult.

// Process the first side (the side with the card number)
const firstImageData = await fileToImageData(firstFile);
const firstProcessResult = session.process(firstImageData);
const status = firstProcessResult.inputImageAnalysisResult.processingStatus;

if (status === "awaiting-other-side") {
// The card has more data on the other side — process it too
const secondImageData = await fileToImageData(secondFile);
session.process(secondImageData);
}

// Retrieve the final result
const result = session.getResult();
console.log("Card number:", result.cardAccounts[0].cardNumber);
console.log("Expiry:", result.cardAccounts[0].expiryDate.originalString);

Clean up​

Release the session and SDK when done.

On Web, call session.delete(), then terminate the core instance.

On Android, close the session and the SDK to release native resources.

On iOS, the session releases its resources when it is deallocated; terminate the SDK when you are done with it.

session.delete();
await blinkCardCore.terminate();