From 22464c434eb7faf3af4c8c44389996925c04eca6 Mon Sep 17 00:00:00 2001 From: xianon Date: Fri, 3 Dec 2021 11:19:28 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=BB=E5=83=8F=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AE=E7=B8=A6=E6=A8=AA=E3=82=B5=E3=82=A4?= =?UTF-8?q?=E3=82=BA=E3=81=AE=E5=8F=96=E5=BE=97=E3=81=A7=20Exif=20Orientat?= =?UTF-8?q?ion=20=E3=82=92=E8=80=83=E6=85=AE=E3=81=99=E3=82=8B=20(#8014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 画像ファイルの縦横サイズの取得で Exif Orientation を考慮する * test: Add rotate.jpg test * Webpublic 画像を返す時のみ Exif Orientation を考慮して縦横サイズを返す * test: Support orientation --- packages/backend/src/misc/get-file-info.ts | 5 ++++ .../backend/src/models/entities/drive-file.ts | 2 +- .../src/models/repositories/drive-file.ts | 20 +++++++++++++- .../backend/src/services/drive/add-file.ts | 4 +++ packages/backend/test/get-file-info.ts | 26 ++++++++++++++++++ packages/backend/test/resources/rotate.jpg | Bin 0 -> 12624 bytes packages/client/src/components/media-list.vue | 21 ++++++++++---- 7 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 packages/backend/test/resources/rotate.jpg diff --git a/packages/backend/src/misc/get-file-info.ts b/packages/backend/src/misc/get-file-info.ts index 39ba541395..8d7f6b1bf9 100644 --- a/packages/backend/src/misc/get-file-info.ts +++ b/packages/backend/src/misc/get-file-info.ts @@ -19,6 +19,7 @@ export type FileInfo = { }; width?: number; height?: number; + orientation?: number; blurhash?: string; warnings: string[]; }; @@ -47,6 +48,7 @@ export async function getFileInfo(path: string): Promise { // image dimensions let width: number | undefined; let height: number | undefined; + let orientation: number | undefined; if (['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/webp', 'image/bmp', 'image/tiff', 'image/svg+xml', 'image/vnd.adobe.photoshop'].includes(type.mime)) { const imageSize = await detectImageSize(path).catch(e => { @@ -61,6 +63,7 @@ export async function getFileInfo(path: string): Promise { } else if (imageSize.wUnits === 'px') { width = imageSize.width; height = imageSize.height; + orientation = imageSize.orientation; // 制限を超えている画像は octet-stream にする if (imageSize.width > 16383 || imageSize.height > 16383) { @@ -87,6 +90,7 @@ export async function getFileInfo(path: string): Promise { type, width, height, + orientation, blurhash, warnings, }; @@ -163,6 +167,7 @@ async function detectImageSize(path: string): Promise<{ height: number; wUnits: string; hUnits: string; + orientation?: number; }> { const readable = fs.createReadStream(path); const imageSize = await probeImageSize(readable); diff --git a/packages/backend/src/models/entities/drive-file.ts b/packages/backend/src/models/entities/drive-file.ts index 698dfac222..4ec7b94ed2 100644 --- a/packages/backend/src/models/entities/drive-file.ts +++ b/packages/backend/src/models/entities/drive-file.ts @@ -77,7 +77,7 @@ export class DriveFile { default: {}, comment: 'The any properties of the DriveFile. For example, it includes image width/height.' }) - public properties: { width?: number; height?: number; avgColor?: string }; + public properties: { width?: number; height?: number; orientation?: number; avgColor?: string }; @Index() @Column('boolean') diff --git a/packages/backend/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts index ddf9a46afd..f2f0308dc0 100644 --- a/packages/backend/src/models/repositories/drive-file.ts +++ b/packages/backend/src/models/repositories/drive-file.ts @@ -28,6 +28,19 @@ export class DriveFileRepository extends Repository { ); } + public getPublicProperties(file: DriveFile): DriveFile['properties'] { + if (file.properties.orientation != null) { + const properties = JSON.parse(JSON.stringify(file.properties)); + if (file.properties.orientation >= 5) { + [properties.width, properties.height] = [properties.height, properties.width]; + } + properties.orientation = undefined; + return properties; + } + + return file.properties; + } + public getPublicUrl(file: DriveFile, thumbnail = false, meta?: Meta): string | null { // リモートかつメディアプロキシ if (file.uri != null && file.userHost != null && config.mediaProxy != null) { @@ -122,7 +135,7 @@ export class DriveFileRepository extends Repository { size: file.size, isSensitive: file.isSensitive, blurhash: file.blurhash, - properties: file.properties, + properties: opts.self ? file.properties : this.getPublicProperties(file), url: opts.self ? file.url : this.getPublicUrl(file, false, meta), thumbnailUrl: this.getPublicUrl(file, true, meta), comment: file.comment, @@ -202,6 +215,11 @@ export const packedDriveFileSchema = { optional: true as const, nullable: false as const, example: 720 }, + orientation: { + type: 'number' as const, + optional: true as const, nullable: false as const, + example: 8 + }, avgColor: { type: 'string' as const, optional: true as const, nullable: false as const, diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts index 6c5fefd4ad..a57f9cf068 100644 --- a/packages/backend/src/services/drive/add-file.ts +++ b/packages/backend/src/services/drive/add-file.ts @@ -372,12 +372,16 @@ export default async function( const properties: { width?: number; height?: number; + orientation?: number; } = {}; if (info.width) { properties['width'] = info.width; properties['height'] = info.height; } + if (info.orientation != null) { + properties['orientation'] = info.orientation; + } const profile = user ? await UserProfiles.findOne(user.id) : null; diff --git a/packages/backend/test/get-file-info.ts b/packages/backend/test/get-file-info.ts index cc9eefbfc6..a0146bd815 100644 --- a/packages/backend/test/get-file-info.ts +++ b/packages/backend/test/get-file-info.ts @@ -17,6 +17,7 @@ describe('Get file info', () => { }, width: undefined, height: undefined, + orientation: undefined, }); })); @@ -34,6 +35,7 @@ describe('Get file info', () => { }, width: 512, height: 512, + orientation: undefined, }); })); @@ -51,6 +53,7 @@ describe('Get file info', () => { }, width: 256, height: 256, + orientation: undefined, }); })); @@ -68,6 +71,7 @@ describe('Get file info', () => { }, width: 256, height: 256, + orientation: undefined, }); })); @@ -85,6 +89,7 @@ describe('Get file info', () => { }, width: 256, height: 256, + orientation: undefined, }); })); @@ -102,6 +107,7 @@ describe('Get file info', () => { }, width: 256, height: 256, + orientation: undefined, }); })); @@ -120,6 +126,7 @@ describe('Get file info', () => { }, width: 256, height: 256, + orientation: undefined, }); })); @@ -137,6 +144,25 @@ describe('Get file info', () => { }, width: 25000, height: 25000, + orientation: undefined, + }); + })); + + it('Rotate JPEG', async (async () => { + const path = `${__dirname}/resources/rotate.jpg`; + const info = await getFileInfo(path) as any; + delete info.warnings; + delete info.blurhash; + assert.deepStrictEqual(info, { + size: 12624, + md5: '68d5b2d8d1d1acbbce99203e3ec3857e', + type: { + mime: 'image/jpeg', + ext: 'jpg' + }, + width: 512, + height: 256, + orientation: 8, }); })); }); diff --git a/packages/backend/test/resources/rotate.jpg b/packages/backend/test/resources/rotate.jpg new file mode 100644 index 0000000000000000000000000000000000000000..477c2baf5bbd0039dc08fa36e3d4b3cd5d39ecb9 GIT binary patch literal 12624 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 { const lightbox = new PhotoSwipeLightbox({ - dataSource: props.mediaList.filter(media => media.type.startsWith('image')).map(media => ({ - src: media.url, - w: media.properties.width, - h: media.properties.height, - alt: media.name, - })), + dataSource: props.mediaList.filter(media => media.type.startsWith('image')).map(media => { + const item = { + src: media.url, + w: media.properties.width, + h: media.properties.height, + alt: media.name, + }; + if (media.properties.orientation != null && media.properties.orientation >= 5) { + [item.w, item.h] = [item.h, item.w]; + } + return item; + }), gallery: gallery.value, children: '.image', thumbSelector: '.image', @@ -77,6 +83,9 @@ export default defineComponent({ itemData.src = file.url; itemData.w = Number(file.properties.width); itemData.h = Number(file.properties.height); + if (file.properties.orientation != null && file.properties.orientation >= 5) { + [itemData.w, itemData.h] = [itemData.h, itemData.w]; + } itemData.msrc = file.thumbnailUrl; itemData.thumbCropped = true; });