Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/export-docx/src/converters/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export async function convertImage(
options: DocxOptions["image"],
): Promise<Paragraph> {
// Get image type from metadata or URL
const getImageType = (metaType?: string): "jpg" | "png" | "gif" | "bmp" => {
const getImageType = (
metaType?: string,
): "jpg" | "png" | "gif" | "bmp" | "webp" => {
// Try metadata type first
switch (metaType) {
case "jpeg":
Expand All @@ -33,6 +35,8 @@ export async function convertImage(
return "gif";
case "bmp":
return "bmp";
case "webp":
return "png";
}

// Fallback to URL-based type detection
Expand All @@ -46,6 +50,8 @@ export async function convertImage(
return "gif";
case "bmp":
return "bmp";
case "webp":
return "png";
default:
return "png";
}
Expand Down
51 changes: 39 additions & 12 deletions packages/export-docx/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ofetch } from "ofetch";
*/
export function getImageTypeFromSrc(
src: string,
): "png" | "jpeg" | "gif" | "bmp" | "tiff" {
): "png" | "jpeg" | "gif" | "bmp" | "tiff" | "webp" {
if (src.startsWith("data:")) {
const match = src.match(/data:image\/(\w+);/);
if (match) {
Expand All @@ -27,6 +27,8 @@ export function getImageTypeFromSrc(
return "bmp";
case "tiff":
return "tiff";
case "webp":
return "webp";
default:
return "png";
}
Expand All @@ -45,6 +47,8 @@ export function getImageTypeFromSrc(
return "bmp";
case "tiff":
return "tiff";
case "webp":
return "webp";
default:
return "png";
}
Expand Down Expand Up @@ -77,12 +81,19 @@ export function createFloatingOptions() {
export function getImageWidth(
node: { attrs?: { width?: number | null } },
options?: { run?: { transformation?: { width?: number } } },
imageMeta?: { width?: number },
imageMeta?: { width?: number | null },
): number {
if (node.attrs?.width) return node.attrs.width;
if (options?.run?.transformation?.width)
if (node.attrs?.width && typeof node.attrs.width === "number") {
return node.attrs.width;
}
if (options?.run?.transformation?.width) {
return options.run.transformation.width;
if (imageMeta?.width) return Math.min(imageMeta.width, 600);
}
if (imageMeta?.width && typeof imageMeta.width === "number") {
const width = Math.min(imageMeta.width, 600);
// 如果图片太小,使用默认尺寸
return width < 50 ? 400 : width;
}
return 400;
}

Expand All @@ -93,13 +104,24 @@ export function getImageHeight(
node: { attrs?: { height?: number | null } },
width: number,
options?: { run?: { transformation?: { height?: number } } },
imageMeta?: { width?: number; height?: number },
imageMeta?: { width?: number | null; height?: number | null },
): number {
if (node.attrs?.height) return node.attrs.height;
if (options?.run?.transformation?.height)
if (node.attrs?.height && typeof node.attrs.height === "number") {
return node.attrs.height;
}
if (options?.run?.transformation?.height) {
return options.run.transformation.height;
if (imageMeta?.width && imageMeta?.height)
return Math.round((width * imageMeta.height) / imageMeta.width);
}
if (
imageMeta?.width &&
typeof imageMeta.width === "number" &&
imageMeta?.height &&
typeof imageMeta.height === "number"
) {
const height = Math.round((width * imageMeta.height) / imageMeta.width);
// 如果计算出的高度太小,使用默认尺寸
return height < 50 ? 300 : height;
}
return 300;
}

Expand All @@ -111,8 +133,13 @@ export async function getImageDataAndMeta(
): Promise<{ data: Uint8Array; meta: ImageMeta }> {
try {
// Use ofetch to get binary data with responseType: "blob"
const blob = await ofetch(url, { responseType: "blob" });
const data = await blob.bytes();
const blob = await ofetch(url, {
responseType: "blob",
redirect: "follow",
timeout: 30000,
});
const arrayBuffer = await blob.arrayBuffer();
const data = new Uint8Array(arrayBuffer);

// Get image metadata using image-meta
let meta: ImageMeta;
Expand Down