mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
use imagemagick and libraw for raw image support (#2668)
* use imagemagick and libraw for raw image support imagemagick and libraw have generally good support for raw images, including Sony's ARW format. These tools should also allow Immich to support many more image formats in future without any major code changes. https://www.libraw.org/supported-cameras I've tested and verified this change with .ARW files and other standard formats. Fixes: #2156 * Add additional type for awr * pr feedback --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
43ec0b77a0
commit
41c2c8b82d
10 changed files with 104 additions and 108 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import type { AssetResponseDto } from '@api';
|
||||
import { describe, expect, it } from '@jest/globals';
|
||||
import { getAssetFilename, getFilenameExtension } from './asset-utils';
|
||||
import { getAssetFilename, getFilenameExtension, getFileMimeType } from './asset-utils';
|
||||
|
||||
describe('get file extension from filename', () => {
|
||||
it('returns the extension without including the dot', () => {
|
||||
|
|
@ -58,3 +58,50 @@ describe('get asset filename', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('get file mime type', () => {
|
||||
for (const { extension, mimeType } of [
|
||||
{ extension: '3gp', mimeType: 'video/3gpp' },
|
||||
{ extension: 'arw', mimeType: 'image/x-sony-arw' },
|
||||
{ extension: 'dng', mimeType: 'image/dng' },
|
||||
{ extension: 'heic', mimeType: 'image/heic' },
|
||||
{ extension: 'heif', mimeType: 'image/heif' },
|
||||
{ extension: 'insp', mimeType: 'image/jpeg' },
|
||||
{ extension: 'insv', mimeType: 'video/mp4' },
|
||||
{ extension: 'nef', mimeType: 'image/x-nikon-nef' },
|
||||
{ extension: 'raf', mimeType: 'image/x-fuji-raf' },
|
||||
{ extension: 'srw', mimeType: 'image/x-samsung-srw' }
|
||||
]) {
|
||||
it(`returns the mime type for ${extension}`, () => {
|
||||
expect(getFileMimeType({ name: `filename.${extension}` } as File)).toEqual(mimeType);
|
||||
});
|
||||
}
|
||||
|
||||
it('returns the mime type from the file', () => {
|
||||
[
|
||||
{
|
||||
file: {
|
||||
name: 'filename.jpg',
|
||||
type: 'image/jpeg'
|
||||
},
|
||||
result: 'image/jpeg'
|
||||
},
|
||||
{
|
||||
file: {
|
||||
name: 'filename.txt',
|
||||
type: 'text/plain'
|
||||
},
|
||||
result: 'text/plain'
|
||||
},
|
||||
{
|
||||
file: {
|
||||
name: 'filename.txt',
|
||||
type: ''
|
||||
},
|
||||
result: ''
|
||||
}
|
||||
].forEach(({ file, result }) => {
|
||||
expect(getFileMimeType(file as File)).toEqual(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -125,34 +125,20 @@ export function getAssetFilename(asset: AssetResponseDto): string {
|
|||
* Returns the MIME type of the file and an empty string when not found.
|
||||
*/
|
||||
export function getFileMimeType(file: File): string {
|
||||
if (file.type !== '') {
|
||||
// Return the MIME type determined by the browser.
|
||||
return file.type;
|
||||
}
|
||||
|
||||
// Return MIME type based on the file extension.
|
||||
switch (getFilenameExtension(file.name)) {
|
||||
case 'heic':
|
||||
return 'image/heic';
|
||||
case 'heif':
|
||||
return 'image/heif';
|
||||
case 'dng':
|
||||
return 'image/dng';
|
||||
case '3gp':
|
||||
return 'video/3gpp';
|
||||
case 'nef':
|
||||
return 'image/x-nikon-nef';
|
||||
case 'raf':
|
||||
return 'image/x-fuji-raf';
|
||||
case 'srw':
|
||||
return 'image/x-samsung-srw';
|
||||
case 'insp':
|
||||
return 'image/jpeg';
|
||||
case 'insv':
|
||||
return 'video/mp4';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
const mimeTypes: Record<string, string> = {
|
||||
'3gp': 'video/3gpp',
|
||||
arw: 'image/x-sony-arw',
|
||||
dng: 'image/dng',
|
||||
heic: 'image/heic',
|
||||
heif: 'image/heif',
|
||||
insp: 'image/jpeg',
|
||||
insv: 'video/mp4',
|
||||
nef: 'image/x-nikon-nef',
|
||||
raf: 'image/x-fuji-raf',
|
||||
srw: 'image/x-samsung-srw'
|
||||
};
|
||||
// Return the MIME type determined by the browser or the MIME type based on the file extension.
|
||||
return file.type || (mimeTypes[getFilenameExtension(file.name)] ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const openFileUploadDialog = async (
|
|||
|
||||
// When adding a content type that is unsupported by browsers, make sure
|
||||
// to also add it to getFileMimeType() otherwise the upload will fail.
|
||||
fileSelector.accept = 'image/*,video/*,.heic,.heif,.dng,.3gp,.nef,.srw,.raf,.insp,.insv';
|
||||
fileSelector.accept = 'image/*,video/*,.heic,.heif,.dng,.3gp,.nef,.srw,.raf,.insp,.insv,.arw';
|
||||
|
||||
fileSelector.onchange = async (e: Event) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue