mirror of
https://github.com/lumina-rocks/lumina.git
synced 2026-04-08 14:36:51 +02:00
rm exif data from images before uploading (#55)
This commit is contained in:
@@ -48,6 +48,57 @@ async function calculateBlurhash(file: File): Promise<string> {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes EXIF metadata from an image by redrawing it on a canvas
|
||||
* @param file The image file to process
|
||||
* @returns A Promise that resolves to a new File object without EXIF data
|
||||
*/
|
||||
async function removeExifData(file: File): Promise<File> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Only process images
|
||||
if (!file.type.startsWith("image/")) {
|
||||
resolve(file)
|
||||
return
|
||||
}
|
||||
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
// Create a canvas with the same dimensions as the image
|
||||
const canvas = document.createElement("canvas")
|
||||
canvas.width = img.width
|
||||
canvas.height = img.height
|
||||
|
||||
// Draw the image to the canvas, which strips EXIF data
|
||||
const ctx = canvas.getContext("2d")
|
||||
if (!ctx) {
|
||||
reject(new Error("Could not get canvas context"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.drawImage(img, 0, 0)
|
||||
|
||||
// Convert canvas to blob with the same type as the original file
|
||||
canvas.toBlob((blob) => {
|
||||
if (!blob) {
|
||||
reject(new Error("Could not create blob from canvas"))
|
||||
return
|
||||
}
|
||||
|
||||
// Create a new File object with the same name and type
|
||||
const sanitizedFile = new File([blob], file.name, {
|
||||
type: file.type,
|
||||
lastModified: file.lastModified
|
||||
})
|
||||
|
||||
resolve(sanitizedFile)
|
||||
}, file.type)
|
||||
}
|
||||
|
||||
img.onerror = () => reject(new Error("Failed to load image"))
|
||||
img.src = URL.createObjectURL(file)
|
||||
})
|
||||
}
|
||||
|
||||
const UploadComponent: React.FC = () => {
|
||||
const { publish } = useNostr()
|
||||
const { createHash } = require("crypto")
|
||||
@@ -102,15 +153,16 @@ const UploadComponent: React.FC = () => {
|
||||
setShouldFetch(true)
|
||||
}, [])
|
||||
|
||||
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const handleFileChange = async (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const file = event.target.files?.[0]
|
||||
if (file) {
|
||||
// Create a clean URL for preview that will be revoked later
|
||||
const url = URL.createObjectURL(file)
|
||||
if (url.startsWith("blob:")) {
|
||||
setPreviewUrl(url)
|
||||
}
|
||||
|
||||
// Optional: Bereinigung alter URLs
|
||||
// Optional: Cleanup old URLs
|
||||
return () => URL.revokeObjectURL(url)
|
||||
}
|
||||
}
|
||||
@@ -125,7 +177,7 @@ const UploadComponent: React.FC = () => {
|
||||
|
||||
const formData = new FormData(event.currentTarget)
|
||||
const desc = formData.get("description") as string
|
||||
const file = formData.get("file") as File
|
||||
let file = formData.get("file") as File
|
||||
let sha256 = ""
|
||||
let finalNoteContent = desc
|
||||
let finalFileUrl = ""
|
||||
@@ -145,16 +197,27 @@ const UploadComponent: React.FC = () => {
|
||||
|
||||
// If file is present, upload it to the media server
|
||||
if (file) {
|
||||
const readFileAsArrayBuffer = (file: File): Promise<ArrayBuffer> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => resolve(reader.result as ArrayBuffer)
|
||||
reader.onerror = () => reject(reader.error)
|
||||
reader.readAsArrayBuffer(file)
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
// Remove EXIF data from image if it's an image file
|
||||
if (file.type.startsWith("image/")) {
|
||||
try {
|
||||
file = await removeExifData(file)
|
||||
console.log("EXIF data removed from image")
|
||||
} catch (error) {
|
||||
console.error("Error removing EXIF data:", error)
|
||||
// Continue with original file if EXIF removal fails
|
||||
}
|
||||
}
|
||||
|
||||
const readFileAsArrayBuffer = (file: File): Promise<ArrayBuffer> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => resolve(reader.result as ArrayBuffer)
|
||||
reader.onerror = () => reject(reader.error)
|
||||
reader.readAsArrayBuffer(file)
|
||||
})
|
||||
}
|
||||
|
||||
const arrayBuffer = await readFileAsArrayBuffer(file)
|
||||
const hashBuffer = createHash("sha256").update(Buffer.from(arrayBuffer)).digest()
|
||||
sha256 = hashBuffer.toString("hex")
|
||||
@@ -256,6 +319,7 @@ const UploadComponent: React.FC = () => {
|
||||
console.log("final Event: ")
|
||||
console.log(signedEvent)
|
||||
publish(signedEvent)
|
||||
// alert("OK:" + signedEvent)
|
||||
}
|
||||
|
||||
setIsLoading(false)
|
||||
|
||||
Reference in New Issue
Block a user