UNPKG

taglib-wasm

Version:

TagLib for TypeScript platforms: Deno, Node.js, Bun, Electron, browsers, and Cloudflare Workers

121 lines (120 loc) 3.84 kB
import { PICTURE_TYPE_VALUES } from "./types.js"; import { applyPictures, readPictures } from "./simple.js"; function pictureToDataURL(picture) { const base64 = btoa(String.fromCharCode(...picture.data)); return `data:${picture.mimeType};base64,${base64}`; } function dataURLToPicture(dataURL, type = "FrontCover", description) { const matches = dataURL.match(/^data:([^;]+);base64,(.+)$/); if (!matches) { throw new Error("Invalid data URL format"); } const [, mimeType, base64] = matches; const binaryString = atob(base64); const data = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { data[i] = binaryString.charCodeAt(i); } return { mimeType, data, type: typeof type === "string" ? PICTURE_TYPE_VALUES[type] : type, description }; } async function setCoverArtFromCanvas(file, canvas, options = {}) { const { format = "image/jpeg", quality = 0.92, type = "FrontCover", description = "Front Cover" } = options; const dataURL = canvas.toDataURL(format, quality); const picture = dataURLToPicture(dataURL, type, description); return applyPictures(file, [picture]); } async function canvasToPicture(canvas, options = {}) { const { format = "image/jpeg", quality = 0.92, type = "FrontCover", description } = options; return new Promise((resolve, reject) => { canvas.toBlob( async (blob) => { if (!blob) { reject(new Error("Failed to convert canvas to blob")); return; } const arrayBuffer = await blob.arrayBuffer(); const data = new Uint8Array(arrayBuffer); resolve({ mimeType: format, data, type: typeof type === "string" ? PICTURE_TYPE_VALUES[type] : type, description }); }, format, quality ); }); } async function imageFileToPicture(file, type = "FrontCover", description) { const arrayBuffer = await file.arrayBuffer(); const data = new Uint8Array(arrayBuffer); return { mimeType: file.type, data, type: typeof type === "string" ? PICTURE_TYPE_VALUES[type] : type, description: description || file.name }; } function displayPicture(picture, imgElement) { if (imgElement.src.startsWith("blob:")) { URL.revokeObjectURL(imgElement.src); } const blob = new Blob([picture.data], { type: picture.mimeType }); const objectURL = URL.createObjectURL(blob); imgElement.src = objectURL; imgElement.addEventListener("load", () => { setTimeout(() => URL.revokeObjectURL(objectURL), 100); }, { once: true }); } function createPictureDownloadURL(picture, filename = "cover") { const blob = new Blob([picture.data], { type: picture.mimeType }); return URL.createObjectURL(blob); } async function createPictureGallery(file, container, options = {}) { const pictures = await readPictures(file); container.innerHTML = ""; pictures.forEach((picture, index) => { const wrapper = document.createElement("div"); wrapper.className = options.className || "picture-item"; const img = document.createElement("img"); displayPicture(picture, img); img.alt = picture.description || `Picture ${index + 1}`; if (options.onClick) { img.style.cursor = "pointer"; img.addEventListener("click", () => options.onClick(picture, index)); } wrapper.appendChild(img); if (options.includeDescription && picture.description) { const caption = document.createElement("p"); caption.textContent = picture.description; wrapper.appendChild(caption); } container.appendChild(wrapper); }); } export { canvasToPicture, createPictureDownloadURL, createPictureGallery, dataURLToPicture, displayPicture, imageFileToPicture, pictureToDataURL, setCoverArtFromCanvas };