Preserve blob content type when stripping EXIF data
This commit is contained in:
parent
fab883c2a6
commit
48cc2b5f11
2 changed files with 74 additions and 3 deletions
68
ts/test-electron/util/scaleImageToLevel_test.ts
Normal file
68
ts/test-electron/util/scaleImageToLevel_test.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { IMAGE_JPEG, IMAGE_PNG } from '../../types/MIME';
|
||||
import * as log from '../../logging/log';
|
||||
|
||||
import { scaleImageToLevel } from '../../util/scaleImageToLevel';
|
||||
|
||||
describe('scaleImageToLevel', () => {
|
||||
// NOTE: These tests are incomplete.
|
||||
|
||||
let objectUrlsToRevoke: Array<string>;
|
||||
function createObjectUrl(blob: Blob): string {
|
||||
const result = URL.createObjectURL(blob);
|
||||
objectUrlsToRevoke.push(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
objectUrlsToRevoke = [];
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
objectUrlsToRevoke.forEach(objectUrl => {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't scale images that are already small enough", async () => {
|
||||
const testCases = [
|
||||
{
|
||||
path: '../fixtures/kitten-1-64-64.jpg',
|
||||
contentType: IMAGE_JPEG,
|
||||
expectedWidth: 64,
|
||||
expectedHeight: 64,
|
||||
},
|
||||
{
|
||||
path: '../fixtures/20x200-yellow.png',
|
||||
contentType: IMAGE_PNG,
|
||||
expectedWidth: 20,
|
||||
expectedHeight: 200,
|
||||
},
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
testCases.map(
|
||||
async ({ path, contentType, expectedWidth, expectedHeight }) => {
|
||||
const blob = await (await fetch(path)).blob();
|
||||
const scaled = await scaleImageToLevel(blob, contentType, true);
|
||||
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
} = await window.Signal.Types.VisualAttachment.getImageDimensions({
|
||||
objectUrl: createObjectUrl(scaled.blob),
|
||||
logger: log,
|
||||
});
|
||||
|
||||
assert.strictEqual(width, expectedWidth);
|
||||
assert.strictEqual(height, expectedHeight);
|
||||
assert.strictEqual(scaled.contentType, contentType);
|
||||
assert.strictEqual(scaled.blob.type, contentType);
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
|
@ -102,10 +102,13 @@ async function getCanvasBlobAsJPEG(
|
|||
return canvasToBlob(canvas, IMAGE_JPEG, quality);
|
||||
}
|
||||
|
||||
async function stripImageFileEXIFData(file: File | Blob): Promise<Blob> {
|
||||
async function stripImageFileEXIFData(
|
||||
file: File | Blob,
|
||||
type: MIMEType
|
||||
): Promise<Blob> {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const xArrayBuffer = await sharp(new Uint8Array(arrayBuffer)).toBuffer();
|
||||
return new Blob([xArrayBuffer]);
|
||||
return new Blob([xArrayBuffer], { type });
|
||||
}
|
||||
|
||||
export async function scaleImageToLevel(
|
||||
|
@ -139,7 +142,7 @@ export async function scaleImageToLevel(
|
|||
MEDIA_QUALITY_LEVEL_DATA.get(level) || DEFAULT_LEVEL_DATA;
|
||||
|
||||
if (fileOrBlobOrURL.size <= thresholdSize) {
|
||||
const blob = await stripImageFileEXIFData(fileOrBlobOrURL);
|
||||
const blob = await stripImageFileEXIFData(fileOrBlobOrURL, contentType);
|
||||
return {
|
||||
blob,
|
||||
contentType,
|
||||
|
|
Loading…
Reference in a new issue