






















@@ -10,7 +10,7 @@ import { assertLocalMediaAllowed } from "../media/local-media-access.js";
1010import {
1111createImageProcessor,
1212getImageMetadata,
13-hasAlphaChannel,
13+readImageProbeFromHeader,
1414} from "../media/media-services.js";
1515import { isPassThroughRemoteMediaSource } from "../media/media-source-url.js";
1616import { MEDIA_MAX_BYTES, saveMediaBuffer, saveMediaSource } from "../media/store.js";
@@ -189,70 +189,37 @@ function getManagedImageMetadataLimitError(
189189return null;
190190}
191191192-function computeManagedImageResizeTarget(
193-metadata: { width: number; height: number },
194-limits: ManagedImageAttachmentLimits,
192+function orientManagedImageMetadata(
193+buffer: Buffer,
194+metadata: { width: number; height: number } | null,
195195): { width: number; height: number } | null {
196-const scale = Math.min(
197-1,
198-limits.maxWidth / metadata.width,
199-limits.maxHeight / metadata.height,
200-Math.sqrt(limits.maxPixels / (metadata.width * metadata.height)),
201-);
202-if (!Number.isFinite(scale) || scale >= 1) {
196+if (!metadata) {
203197return null;
204198}
205-206-let width = Math.max(1, Math.floor(metadata.width * scale));
207-let height = Math.max(1, Math.floor(metadata.height * scale));
208-while (
209-width > limits.maxWidth ||
210-height > limits.maxHeight ||
211-width * height > limits.maxPixels
212-) {
213-if (width >= height && width > 1) {
214-width -= 1;
215-} else if (height > 1) {
216-height -= 1;
217-} else {
218-break;
219-}
220-}
221-return { width, height };
199+const orientation = readImageProbeFromHeader(buffer)?.orientation;
200+return orientation === 5 || orientation === 6 || orientation === 7 || orientation === 8
201+ ? { width: metadata.height, height: metadata.width }
202+ : metadata;
222203}
223204224205async function resizeManagedImageBufferToLimits(params: {
225206buffer: Buffer;
226-contentType: string;
227-metadata: { width: number; height: number };
228207limits: ManagedImageAttachmentLimits;
229208}): Promise<{ buffer: Buffer; contentType: string; width: number; height: number }> {
230-const target = computeManagedImageResizeTarget(params.metadata, params.limits);
231-if (!target) {
232-return {
233-buffer: params.buffer,
234-contentType: params.contentType,
235-width: params.metadata.width,
236-height: params.metadata.height,
237-};
238-}
239-240-const preserveAlpha = await hasAlphaChannel(params.buffer);
241-const resized = await createImageProcessor().encodeBest(params.buffer, {
242-resize: {
243-width: target.width,
244-height: target.height,
245-fit: "inside",
246-enlarge: false,
209+const resized = await createImageProcessor().encodeToLimits(params.buffer, {
210+limits: {
211+maxWidth: params.limits.maxWidth,
212+maxHeight: params.limits.maxHeight,
213+maxPixels: params.limits.maxPixels,
247214},
248215opaque: { format: "jpeg", quality: 92 },
249216transparent: { format: "png", compressionLevel: 9 },
250-transparency: preserveAlpha ? "preserve" : "flatten",
217+transparency: "auto",
251218});
252219253220return {
254221buffer: resized.data,
255-contentType: resized.format === "png" ? "image/png" : "image/jpeg",
222+contentType: resized.mimeType,
256223width: resized.width,
257224height: resized.height,
258225};
@@ -851,7 +818,8 @@ export async function createManagedOutgoingImageBlocks(params: {
851818originalStats.width != null && originalStats.height != null
852819 ? { width: originalStats.width, height: originalStats.height }
853820 : await getImageMetadata(originalBuffer);
854-let effectiveMetadata = originalMetadata;
821+const originalDisplayMetadata = orientManagedImageMetadata(originalBuffer, originalMetadata);
822+let effectiveMetadata = originalDisplayMetadata;
855823let metadataLimitError = getManagedImageMetadataLimitError(effectiveMetadata, alt, limits);
856824for (let resizeAttempt = 0; metadataLimitError; resizeAttempt += 1) {
857825if (!effectiveMetadata) {
@@ -862,8 +830,6 @@ export async function createManagedOutgoingImageBlocks(params: {
862830}
863831const resized = await resizeManagedImageBufferToLimits({
864832buffer: originalBuffer,
865-contentType: savedOriginalContentType,
866-metadata: effectiveMetadata,
867833 limits,
868834});
869835validateManagedImageBuffer(resized.buffer, alt, limits);
@@ -880,16 +846,20 @@ export async function createManagedOutgoingImageBlocks(params: {
880846savedOriginalPath = savedOriginal.path;
881847originalBuffer = resized.buffer;
882848originalStats = await getVariantStats(savedOriginal.path);
883-effectiveMetadata =
849+effectiveMetadata = orientManagedImageMetadata(
850+originalBuffer,
884851originalStats.width != null && originalStats.height != null
885852 ? { width: originalStats.width, height: originalStats.height }
886- : await getImageMetadata(originalBuffer);
853+ : await getImageMetadata(originalBuffer),
854+);
887855metadataLimitError = getManagedImageMetadataLimitError(effectiveMetadata, alt, limits);
888856if (!metadataLimitError) {
889857resizeWarning = buildManagedImageResizeWarningBlock({
890858 alt,
891-originalWidth: originalMetadata?.width ?? effectiveMetadata?.width ?? resized.width,
892-originalHeight: originalMetadata?.height ?? effectiveMetadata?.height ?? resized.height,
859+originalWidth:
860+originalDisplayMetadata?.width ?? effectiveMetadata?.width ?? resized.width,
861+originalHeight:
862+originalDisplayMetadata?.height ?? effectiveMetadata?.height ?? resized.height,
893863resizedWidth: effectiveMetadata?.width ?? resized.width,
894864resizedHeight: effectiveMetadata?.height ?? resized.height,
895865});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。