typescript - Hur får man bredd/höjd på en base64-bild i deno?
Detta är en upprepning av denna fråga: Hämta bildens bredd och höjd från Base64-koden i JavaScript, men jag frågar med avseende på Deno. Deno har inte new Image() som används i alla lösningar jag har läst. Jag avser att göra detta i en edge-funktion så minskade beroenden är viktiga. Några saker jag har övervägt:
- https://github.com/DjDeveloperr/skia_canvas Men den Edge-miljö jag arbetar i tillåter inte skrivåtkomst, vilket krävs för att använda detta.
- https://github.com/matmen/ImageScript Men jag vet inte den relevanta deno http-adressen att importera den från
Finns det ett sätt att göra detta utan ett paket eller att göra det enkelt med något inbyggt paket?
Svar #1
För att få bildens bredd och höjd utan externa bibliotek behöver du analysera bildhuvudet. Om du bara hanterar ett fåtal bildtyper kan du enkelt undvika att använda tredjepartslösningar.
Till exempel för att analysera en PNG-bilds bredd och höjd från en base64-kodad bild kan du göra det så här:
import { decode } from "https://deno.land/std/encoding/base64.ts"
const pngImageb64 = /* some png image in base64 */
const pngImage = decode(pngImageb64);
const dataView = new DataView(pngImage.buffer);
// The width and height are 4-byte integers starting
// at byte offset 16 and 20, respectively.
const width = dataView.getUint32(16);
const height = dataView.getUint32(20);
Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
Bredd och höjd anger bildens dimensioner i pixlar. De är 4-byte heltal. Noll är ett ogiltigt värde. Maxvärdet för vardera är 2^31
För jpeg är det lite svårare eftersom dimensionerna lagras i Start of Frame (SOF)-markörerna. Följande bör fungera i de flesta fall (har bara testat det i några få jpegar)
const jpegImageb64 = /* some jpeg image in base64 */
const jpegImage = decode(jpegImageb64);
const dataView = new DataView(jpegImage.buffer);
let width, height;
for (let i = 0; i < dataView.byteLength - 9; i++) { // - 9 prevent out-of-bounds access
if (dataView.getUint16(i) === 0xFFC0 || dataView.getUint16(i) === 0xFFC2) {
height = dataView.getUint16(i + 5);
width = dataView.getUint16(i + 7);
break;
}
}
Andra möjliga lösningar:
- Analyserar JPEG SOS-markör
- Hämtar bildstorlek på JPEG från dess binära data
För att upptäcka bildtypen så att du vet vilken parser du ska använda, måste du läsa de första bytena av bilden, du kan använda file-type-biblioteket för det (efter att ha avkodat base64)
Se https://github.com/sindresorhus/file-type/blob/5c42f8057f056fe41cbe4bffb53f56987d02e909/core.js#L238-L249 för att själv upptäcka jpeg.
Beroende på vilken typ av bild du hanterar kan det vara mer komplicerat. Om du stödjer ett brett utbud av bildformat skulle jag rekommendera att använda ett bibliotek som sharp för att analysera den datan.
