Skip to content

Commit 3433753

Browse files
committed
fix: preserve original filename and extension for single-image print
Single images were converted to a client-side PDF named after the image (photo.pdf), so the UI and submission showed a .pdf name even though the user picked photo.png/.jpg. PDF content also cannot be renamed back to .png/.jpg or the backend tries to decode the PDF bytes as an image. Stop converting single images to PDF. Pass the original image straight through (new prepareImageFile helper) so the backend renders it onto A4 itself via ConvertImageToPDF — png/jpg/jpeg keep their exact filename, gif/webp/bmp are normalized to JPEG first since the backend only decodes those three. N-up stays disabled for a single page, so no PDF-only code path is reached. Batch images still merge into images.pdf as before.
1 parent 89ec491 commit 3433753

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/lib/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,22 @@ const normalizeImageToJpeg = (file: File): Promise<ArrayBuffer> =>
9090
img.src = objectUrl;
9191
});
9292

93+
// Image formats the backend renders onto A4 directly. Other image types
94+
// (gif/webp/bmp) must be normalized to JPEG first.
95+
const BACKEND_IMAGE_EXTS = new Set(["png", "jpg", "jpeg"]);
96+
97+
// Returns a single-image File ready for preview/submit: png/jpg/jpeg pass
98+
// through unchanged so the original filename and extension are preserved,
99+
// while unsupported types are normalized to JPEG.
100+
export const prepareImageFile = async (file: File): Promise<File> => {
101+
const ext = getFileExtension(file.name);
102+
if (BACKEND_IMAGE_EXTS.has(ext)) return file;
103+
const buf = await normalizeImageToJpeg(file);
104+
return new File([buf], file.name.replace(/\.[^.]+$/, "") + ".jpg", {
105+
type: "image/jpeg",
106+
});
107+
};
108+
93109
export const imagesToPdf = async (files: File[]): Promise<Blob> => {
94110
const { PDFDocument } = await import("pdf-lib");
95111
const pdf = await PDFDocument.create();

src/pages/Printers.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
downloadFile,
4545
imagesToPdf,
4646
createNupPdf,
47+
prepareImageFile,
4748
} from "@/lib/utils";
4849
import {
4950
isInFeishu,
@@ -667,16 +668,17 @@ function PrinterContent() {
667668
const merge = async () => {
668669
setMerging(true);
669670
try {
670-
const blob = await imagesToPdf(imageFiles);
671671
if (!cancelled) {
672-
// For a single image, keep the original filename (e.g. photo.jpg →
673-
// photo.pdf) so the UI and submission reflect what the user picked;
674-
// fall back to images.pdf only when merging multiple images.
675-
const pdfName =
676-
imageFiles.length === 1
677-
? imageFiles[0].name.replace(/\.[^.]+$/, "") + ".pdf"
678-
: "images.pdf";
679-
setFile(new File([blob], pdfName, { type: "application/pdf" }));
672+
if (imageFiles.length === 1) {
673+
// Single image: pass the image through unchanged (the backend
674+
// renders it onto A4), so the original filename/extension is
675+
// preserved instead of becoming *.pdf. Unsupported image types
676+
// are normalized to JPEG first.
677+
setFile(await prepareImageFile(imageFiles[0]));
678+
} else {
679+
const blob = await imagesToPdf(imageFiles);
680+
setFile(new File([blob], "images.pdf", { type: "application/pdf" }));
681+
}
680682
}
681683
} catch (err: unknown) {
682684
if (!cancelled) {

0 commit comments

Comments
 (0)