mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 03:03:09 +02:00
fix(backend/DriveService): convert WebP/AVIF to WebP (#10239)
* fix(backend/DriveService): convert transparent WebP/AVIF to PNG * webpにする その希望が複数ありましたので * Update packages/backend/src/core/DriveService.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * update test * webpはwebpublicにできる --------- Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> Co-authored-by: tamaina <tamaina@hotmail.co.jp>
This commit is contained in:
parent
e0b7633a7a
commit
3f53cbd8f6
8 changed files with 86 additions and 42 deletions
|
@ -299,7 +299,7 @@ export class DriveService {
|
|||
}
|
||||
|
||||
satisfyWebpublic = !!(
|
||||
type !== 'image/svg+xml' && type !== 'image/webp' && type !== 'image/avif' &&
|
||||
type !== 'image/svg+xml' && type !== 'image/avif' &&
|
||||
!(metadata.exif ?? metadata.iptc ?? metadata.xmp ?? metadata.tifftagPhotoshop) &&
|
||||
metadata.width && metadata.width <= 2048 &&
|
||||
metadata.height && metadata.height <= 2048
|
||||
|
@ -319,11 +319,11 @@ export class DriveService {
|
|||
this.registerLogger.info('creating web image');
|
||||
|
||||
try {
|
||||
if (['image/jpeg', 'image/webp', 'image/avif'].includes(type)) {
|
||||
if (type === 'image/jpeg') {
|
||||
webpublic = await this.imageProcessingService.convertSharpToJpeg(img, 2048, 2048);
|
||||
} else if (['image/png'].includes(type)) {
|
||||
webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
|
||||
} else if (['image/svg+xml'].includes(type)) {
|
||||
} else if (['image/webp', 'image/avif'].includes(type)) {
|
||||
webpublic = await this.imageProcessingService.convertSharpToWebp(img, 2048, 2048);
|
||||
} else if (['image/png', 'image/svg+xml'].includes(type)) {
|
||||
webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
|
||||
} else {
|
||||
this.registerLogger.debug('web image not created (not an required image)');
|
||||
|
|
|
@ -155,7 +155,7 @@ export class ApRendererService {
|
|||
public renderDocument(file: DriveFile): IApDocument {
|
||||
return {
|
||||
type: 'Document',
|
||||
mediaType: file.type,
|
||||
mediaType: file.webpublicType ?? file.type,
|
||||
url: this.driveFileEntityService.getPublicUrl(file),
|
||||
name: file.comment,
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as assert from 'assert';
|
|||
// node-fetch only supports it's own Blob yet
|
||||
// https://github.com/node-fetch/node-fetch/pull/1664
|
||||
import { Blob } from 'node-fetch';
|
||||
import { startServer, signup, post, api, uploadFile } from '../utils.js';
|
||||
import { startServer, signup, post, api, uploadFile, simpleGet } from '../utils.js';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
|
||||
describe('Endpoints', () => {
|
||||
|
@ -439,6 +439,45 @@ describe('Endpoints', () => {
|
|||
assert.strictEqual(res.body.name, 'image.svg');
|
||||
assert.strictEqual(res.body.type, 'image/svg+xml');
|
||||
});
|
||||
|
||||
for (const type of ['webp', 'avif']) {
|
||||
const mediaType = `image/${type}`;
|
||||
|
||||
const getWebpublicType = async (user: any, fileId: string): Promise<string> => {
|
||||
// drive/files/create does not expose webpublicType directly, so get it by posting it
|
||||
const res = await post(user, {
|
||||
text: mediaType,
|
||||
fileIds: [fileId],
|
||||
});
|
||||
const apRes = await simpleGet(`notes/${res.id}`, 'application/activity+json');
|
||||
assert.strictEqual(apRes.status, 200);
|
||||
assert.ok(Array.isArray(apRes.body.attachment));
|
||||
return apRes.body.attachment[0].mediaType;
|
||||
};
|
||||
|
||||
test(`透明な${type}ファイルを作成できる`, async () => {
|
||||
const path = `with-alpha.${type}`;
|
||||
const res = await uploadFile(alice, { path });
|
||||
|
||||
assert.strictEqual(res.status, 200);
|
||||
assert.strictEqual(res.body.name, path);
|
||||
assert.strictEqual(res.body.type, mediaType);
|
||||
|
||||
const webpublicType = await getWebpublicType(alice, res.body.id);
|
||||
assert.strictEqual(webpublicType, 'image/webp');
|
||||
});
|
||||
|
||||
test(`透明じゃない${type}ファイルを作成できる`, async () => {
|
||||
const path = `without-alpha.${type}`;
|
||||
const res = await uploadFile(alice, { path });
|
||||
assert.strictEqual(res.status, 200);
|
||||
assert.strictEqual(res.body.name, path);
|
||||
assert.strictEqual(res.body.type, mediaType);
|
||||
|
||||
const webpublicType = await getWebpublicType(alice, res.body.id);
|
||||
assert.strictEqual(webpublicType, 'image/webp');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('drive/files/update', () => {
|
||||
|
|
BIN
packages/backend/test/resources/with-alpha.avif
Normal file
BIN
packages/backend/test/resources/with-alpha.avif
Normal file
Binary file not shown.
BIN
packages/backend/test/resources/with-alpha.webp
Normal file
BIN
packages/backend/test/resources/with-alpha.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
packages/backend/test/resources/without-alpha.avif
Normal file
BIN
packages/backend/test/resources/without-alpha.avif
Normal file
Binary file not shown.
BIN
packages/backend/test/resources/without-alpha.webp
Normal file
BIN
packages/backend/test/resources/without-alpha.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -204,7 +204,12 @@ export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status:
|
|||
redirect: 'manual',
|
||||
});
|
||||
|
||||
const body = res.headers.get('content-type') === 'application/json; charset=utf-8'
|
||||
const jsonTypes = [
|
||||
'application/json; charset=utf-8',
|
||||
'application/activity+json; charset=utf-8',
|
||||
];
|
||||
|
||||
const body = jsonTypes.includes(res.headers.get('content-type') ?? '')
|
||||
? await res.json()
|
||||
: null;
|
||||
|
||||
|
|
Loading…
Reference in a new issue