1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 15:11:58 +00:00

fix(server): orientation handling for person thumbnails (#10382)

fix orientation handling
This commit is contained in:
Mert 2024-06-16 11:45:58 -04:00 committed by GitHub
parent 0b08af7082
commit e77e87b936
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 27 deletions

View file

@ -47,6 +47,10 @@ export interface ImageDimensions {
height: number;
}
export interface InputDimensions extends ImageDimensions {
inputPath: string;
}
export interface VideoInfo {
format: VideoFormat;
videoStreams: VideoStreamInfo[];

View file

@ -917,9 +917,9 @@ describe(PersonService.name, () => {
colorspace: Colorspace.P3,
crop: {
left: 0,
top: 428,
width: 1102,
height: 1102,
top: 85,
width: 510,
height: 510,
},
},
);

View file

@ -41,13 +41,12 @@ import {
} from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { BoundingBox, IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
import { CropOptions, IMediaRepository, ImageDimensions } from 'src/interfaces/media.interface';
import { CropOptions, IMediaRepository, ImageDimensions, InputDimensions } from 'src/interfaces/media.interface';
import { IMoveRepository } from 'src/interfaces/move.interface';
import { IPersonRepository, UpdateFacesData } from 'src/interfaces/person.interface';
import { ISearchRepository } from 'src/interfaces/search.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { Orientation } from 'src/services/metadata.service';
import { CacheControl, ImmichFileResponse } from 'src/utils/file';
import { mimeTypes } from 'src/utils/mime-types';
import { isFacialRecognitionEnabled } from 'src/utils/misc';
@ -520,7 +519,7 @@ export class PersonService {
return JobStatus.FAILED;
}
const { width, height, inputPath } = await this.getInputDimensions(asset);
const { width, height, inputPath } = await this.getInputDimensions(asset, { width: oldWidth, height: oldHeight });
const thumbnailPath = StorageCore.getPersonThumbnailPath(person);
this.storageCore.ensureFolders(thumbnailPath);
@ -601,7 +600,7 @@ export class PersonService {
return person;
}
private async getInputDimensions(asset: AssetEntity): Promise<ImageDimensions & { inputPath: string }> {
private async getInputDimensions(asset: AssetEntity, oldDims: ImageDimensions): Promise<InputDimensions> {
if (!asset.exifInfo?.exifImageHeight || !asset.exifInfo.exifImageWidth) {
throw new Error(`Asset ${asset.id} dimensions are unknown`);
}
@ -611,10 +610,11 @@ export class PersonService {
}
if (asset.type === AssetType.IMAGE) {
const { width, height } = this.withOrientation(asset.exifInfo.orientation as Orientation, {
width: asset.exifInfo.exifImageWidth,
height: asset.exifInfo.exifImageHeight,
});
let { exifImageWidth: width, exifImageHeight: height } = asset.exifInfo;
if (oldDims.height > oldDims.width !== height > width) {
[width, height] = [height, width];
}
return { width, height, inputPath: asset.originalPath };
}
@ -622,20 +622,6 @@ export class PersonService {
return { width, height, inputPath: asset.previewPath };
}
private withOrientation(orientation: Orientation, { width, height }: ImageDimensions): ImageDimensions {
switch (orientation) {
case Orientation.MirrorHorizontalRotate270CW:
case Orientation.Rotate90CW:
case Orientation.MirrorHorizontalRotate90CW:
case Orientation.Rotate270CW: {
return { width: height, height: width };
}
default: {
return { width, height };
}
}
}
private getCrop(dims: { old: ImageDimensions; new: ImageDimensions }, { x1, y1, x2, y2 }: BoundingBox): CropOptions {
const widthScale = dims.new.width / dims.old.width;
const heightScale = dims.new.height / dims.old.height;

View file

@ -72,8 +72,8 @@ export const faceStub = {
boundingBoxY1: 5,
boundingBoxX2: 505,
boundingBoxY2: 505,
imageHeight: 1000,
imageWidth: 1000,
imageHeight: 2880,
imageWidth: 2160,
}),
middle: Object.freeze<NonNullableProperty<AssetFaceEntity>>({
id: 'assetFaceId6',