Ctrl K
ComunidadGuías…

src/lib/shrink-picture.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
const JPEG_QUALITY = 0.85;

/**
 * Redraws a picture as a JPEG of no more than `maxEdge` pixels on its long edge.
 *
 * A printed page embeds every picture at its full pixel size, and only a JPEG goes in
 * as it is: Chrome re-encodes anything else losslessly, so a 1000-pixel PNG drawn an
 * inch wide costs over a megabyte of PDF. Transparency is flattened onto white, the
 * paper it prints on. Whatever cannot be decoded or drawn here comes back unchanged -
 * a heavy picture beats a missing one.
 */
export async function shrinkPicture(
  blob: Blob,
  maxEdge: number,
): Promise<Blob> {
  if (typeof createImageBitmap !== "function") return blob;
  let bitmap: ImageBitmap;
  try {
    bitmap = await createImageBitmap(blob);
  } catch {
    return blob;
  }
  try {
    const scale = Math.min(1, maxEdge / Math.max(bitmap.width, bitmap.height));
    if (scale === 1 && blob.type === "image/jpeg") return blob;

    const canvas = document.createElement("canvas");
    canvas.width = Math.max(1, Math.round(bitmap.width * scale));
    canvas.height = Math.max(1, Math.round(bitmap.height * scale));
    const context = canvas.getContext("2d");
    if (!context) return blob;
    context.fillStyle = "#fff";
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.imageSmoothingQuality = "high";
    context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);

    const shrunk = await new Promise<Blob | null>((resolve) =>
      canvas.toBlob(resolve, "image/jpeg", JPEG_QUALITY),
    );
    return shrunk ?? blob;
  } finally {
    bitmap.close();
  }
}