vue-qrcode-reader
vue-qrcode-reader copied to clipboard
Feature Request: PDF-Support for Dropzone
Hey everyone, would it be possible to add support to analyze detection of qr-codes within pdf-files. We have protocolls as pdfs, where a qr-code sticker is glued on the bottom of the page and is afterwards scanned into pdf-file.
This would be very amazing, if its possible.
https://stackoverflow.com/questions/12921052/parsing-pdf-pages-as-javascript-images
Puh, that sounds a bit out-of-scope. I think it's not worth pulling in a PDF parsing dependency for this feature. But you can easily implement this yourself. QrcodeDropZone
is not a complicated component. The main complexity of this library comes from QrcodeStream
.
Haven't tested (or even type checked) this at all but if I just inline all internal dependencies of QrcodeDropZone
I get the following component (and you can probably remove a good chunk of that):
<template>
<div
@drop.prevent.stop="onDrop"
@dragenter.prevent.stop="onDragOver(true)"
@dragleave.prevent.stop="onDragOver(false)"
@dragover.prevent.stop
>
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { type DetectedBarcode, type BarcodeFormat, BarcodeDetector } from 'barcode-detector/pure'
import { type PropType } from 'vue'
import { type BarcodeFormat } from 'barcode-detector/pure'
const props = defineProps({
formats: {
type: Array as PropType<BarcodeFormat[]>,
default: () => ['qr_code'] as BarcodeFormat[]
}
})
const emit = defineEmits(['detect', 'dragover', 'error'])
// methods
export const eventOn = (
eventTarget: EventTarget,
successEvent: string,
errorEvent = 'error'
): Promise<Event> => {
let $resolve: (value: Event) => void
let $reject: (reason?: Event) => void
const promise = new Promise(
(resolve: (value: Event) => void, reject: (reason?: Event) => void) => {
$resolve = resolve
$reject = reject
eventTarget.addEventListener(successEvent, $resolve)
eventTarget.addEventListener(errorEvent, $reject)
}
)
promise.finally(() => {
eventTarget.removeEventListener(successEvent, $resolve)
eventTarget.removeEventListener(errorEvent, $reject)
})
return promise
}
const imageElementFromUrl = async (url: string) => {
if (url.startsWith('http') && url.includes(location.host) === false) {
throw new DropImageFetchError()
}
const image = document.createElement('img')
image.src = url
await eventOn(image, 'load')
return image
}
export const processFile = async (
file: File,
formats: BarcodeFormat[] = ['qr_code']
): Promise<DetectedBarcode[]> => {
const barcodeDetector = new BarcodeDetector({
formats
})
return await barcodeDetector.detect(file)
}
export const processUrl = async (
url: string,
formats: BarcodeFormat[] = ['qr_code']
): Promise<DetectedBarcode[]> => {
const barcodeDetector = new BarcodeDetector({
formats
})
const image = await imageElementFromUrl(url)
return await barcodeDetector.detect(image)
}
const onDetect = async (promise: Promise<any>) => {
try {
const detectedCodes = await promise
emit('detect', detectedCodes)
} catch (error) {
emit('error', error)
}
}
const onDragOver = (isDraggingOver: boolean) => {
emit('dragover', isDraggingOver)
}
const onDrop = ({ dataTransfer }: DragEvent) => {
if (!dataTransfer) return
onDragOver(false)
const droppedFiles = [...Array.from(dataTransfer.files)]
const droppedUrl = dataTransfer.getData('text/uri-list')
droppedFiles.forEach((file: File) => {
onDetect(processFile(file))
})
if (droppedUrl !== '') {
onDetect(processUrl(droppedUrl, props.formats))
}
}
</script>
Thank you for your response. https://www.npmjs.com/package/pdf-img-convert it has Unpacked Size of 12.9 kB, so maybe this could be suiteable, without adding a huge overhead, like pdf.js
would this be an option or do you dont wanna use any other packages? I think such feature would let other users also benefit :)
Sorry man, I think this is too edge case-y. So I think the dependency is not worth it. We could think of some mechanism to intercept file processing fron the outside, but that would probably be more complicated then implementing the component yourself.
We could leave this issue open for other users to give their two cents but the issue will be auto-closed in a month or so.
This issue has been marked as stale. If there is no further activity it will be closed.