partial implementation of bar code parsing from PDF
This commit is contained in:
59
app/lib/pdf/pdf2png.ts
Normal file
59
app/lib/pdf/pdf2png.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { PDFPageProxy } from 'pdfjs-dist';
|
||||
import { BrowserPDF417Reader } from '@zxing/browser';
|
||||
import * as pdfJSx from 'pdfjs-dist';
|
||||
|
||||
|
||||
/**
|
||||
* Render the first page of a PDF document onto a new canvas.
|
||||
* @param {Event} event - The change event from an HTMLInputElement.
|
||||
* @return {Promise<HTMLCanvasElement | null>} The canvas with the first page of the PDF, or null if the document is not a PDF.
|
||||
*/
|
||||
export async function pdf2canvas(event: React.ChangeEvent<HTMLInputElement>): Promise<HTMLCanvasElement | null> {
|
||||
const file = (event.target as HTMLInputElement).files?.[0];
|
||||
|
||||
if(!file) {
|
||||
console.error('No file was selected.');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (file.type !== 'application/pdf') {
|
||||
console.error(file.name, 'is not a .pdf file.');
|
||||
return null;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
const data = await new Promise<Uint8Array>((resolve, reject) => {
|
||||
reader.onload = (e) => resolve(new Uint8Array((e.target as FileReader).result as ArrayBuffer));
|
||||
reader.onerror = (e) => reject(e);
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
|
||||
const pdfJS = await import('pdfjs-dist');
|
||||
|
||||
// worker file was manually copied to the `public` folder
|
||||
pdfJS.GlobalWorkerOptions.workerSrc = window.location.origin + '/pdf.worker.min.mjs';
|
||||
|
||||
const pdf = await pdfJS.getDocument(data).promise;
|
||||
|
||||
const page: PDFPageProxy = await pdf.getPage(1);
|
||||
|
||||
const scale = 1.5;
|
||||
const viewport = page.getViewport({ scale });
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
await page.render({ canvasContext: context as CanvasRenderingContext2D, viewport }).promise;
|
||||
|
||||
const codeReader = new BrowserPDF417Reader();
|
||||
|
||||
const result = await codeReader.decodeFromCanvas(canvas);
|
||||
|
||||
console.log(result);
|
||||
|
||||
// codeReader.decode(imageData);
|
||||
|
||||
return null;
|
||||
}
|
||||
9
app/lib/pdf/pdfjs.ts
Normal file
9
app/lib/pdf/pdfjs.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import * as pdfjsModule from 'pdfjs-dist';
|
||||
|
||||
const pdfjs = (
|
||||
'default' in pdfjsModule ? pdfjsModule['default'] : pdfjsModule
|
||||
) as typeof pdfjsModule;
|
||||
|
||||
export default pdfjs;
|
||||
@@ -7,6 +7,7 @@ import { useFormState } from "react-dom";
|
||||
import { updateOrAddBill } from "../lib/actions/billActions";
|
||||
import Link from "next/link";
|
||||
import { formatYearMonth } from "../lib/format";
|
||||
import { pdf2canvas } from "../lib/pdf/pdf2png";
|
||||
|
||||
// Next.js does not encode an utf-8 file name correctly when sending a form with a file attachment
|
||||
// This is a workaround for that
|
||||
@@ -34,10 +35,14 @@ export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => {
|
||||
|
||||
const [ isPaid, setIsPaid ] = React.useState<boolean>(paid);
|
||||
|
||||
const billPaid_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const billPaid_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsPaid(event.target.checked);
|
||||
}
|
||||
|
||||
const billAttachment_handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
pdf2canvas(event);
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="card card-compact card-bordered bg-base-100 shadow-s">
|
||||
<div className="card-body">
|
||||
@@ -70,7 +75,7 @@ export const BillEditForm:FC<BillEditFormProps> = ({ location, bill }) => {
|
||||
</Link>
|
||||
: null
|
||||
}
|
||||
<input id="billAttachment" name="billAttachment" type="file" className="file-input file-input-bordered max-w-sm w-full file-input-xs my-2 block" />
|
||||
<input id="billAttachment" name="billAttachment" type="file" className="file-input file-input-bordered max-w-sm w-full file-input-xs my-2 block" onChange={billAttachment_handleChange} />
|
||||
<div id="status-error" aria-live="polite" aria-atomic="true">
|
||||
{state.errors?.billAttachment &&
|
||||
state.errors.billAttachment.map((error: string) => (
|
||||
|
||||
Reference in New Issue
Block a user