mirror of
https://github.com/immich-app/immich.git
synced 2026-03-01 10:08:42 +03:00
fix: face and edit handling (#25738)
* fix: handle edits when creating face
This commit is contained in:
@@ -44,6 +44,7 @@ import { getDimensions } from 'src/utils/asset.util';
|
||||
import { ImmichFileResponse } from 'src/utils/file';
|
||||
import { mimeTypes } from 'src/utils/mime-types';
|
||||
import { isFacialRecognitionEnabled } from 'src/utils/misc';
|
||||
import { Point, transformPoints } from 'src/utils/transform';
|
||||
|
||||
@Injectable()
|
||||
export class PersonService extends BaseService {
|
||||
@@ -634,15 +635,61 @@ export class PersonService extends BaseService {
|
||||
this.requireAccess({ auth, permission: Permission.PersonRead, ids: [dto.personId] }),
|
||||
]);
|
||||
|
||||
const asset = await this.assetRepository.getById(dto.assetId, { edits: true, exifInfo: true });
|
||||
if (!asset) {
|
||||
throw new NotFoundException('Asset not found');
|
||||
}
|
||||
|
||||
const edits = asset.edits || [];
|
||||
|
||||
let topLeft: Point = { x: dto.x, y: dto.y };
|
||||
let bottomRight: Point = { x: dto.x + dto.width, y: dto.y + dto.height };
|
||||
|
||||
// the coordinates received from the client are based on the edited preview image
|
||||
// we need to convert them to the coordinate space of the original unedited image
|
||||
if (edits.length > 0) {
|
||||
if (!asset.width || !asset.height || !asset.exifInfo?.exifImageWidth || !asset.exifInfo?.exifImageHeight) {
|
||||
throw new BadRequestException('Asset does not have valid dimensions');
|
||||
}
|
||||
|
||||
// convert from preview to full dimensions
|
||||
const scaleFactor = asset.width / dto.imageWidth;
|
||||
topLeft = { x: topLeft.x * scaleFactor, y: topLeft.y * scaleFactor };
|
||||
bottomRight = { x: bottomRight.x * scaleFactor, y: bottomRight.y * scaleFactor };
|
||||
|
||||
const {
|
||||
points: [invertedTopLeft, invertedBottomRight],
|
||||
} = transformPoints(
|
||||
[topLeft, bottomRight],
|
||||
edits,
|
||||
{ width: asset.width, height: asset.height },
|
||||
{ inverse: true },
|
||||
);
|
||||
|
||||
// make sure topLeft is top-left and bottomRight is bottom-right
|
||||
topLeft = {
|
||||
x: Math.min(invertedTopLeft.x, invertedBottomRight.x),
|
||||
y: Math.min(invertedTopLeft.y, invertedBottomRight.y),
|
||||
};
|
||||
bottomRight = {
|
||||
x: Math.max(invertedTopLeft.x, invertedBottomRight.x),
|
||||
y: Math.max(invertedTopLeft.y, invertedBottomRight.y),
|
||||
};
|
||||
|
||||
// now coordinates are in original image space
|
||||
dto.imageHeight = asset.exifInfo.exifImageHeight;
|
||||
dto.imageWidth = asset.exifInfo.exifImageWidth;
|
||||
}
|
||||
|
||||
await this.personRepository.createAssetFace({
|
||||
personId: dto.personId,
|
||||
assetId: dto.assetId,
|
||||
imageHeight: dto.imageHeight,
|
||||
imageWidth: dto.imageWidth,
|
||||
boundingBoxX1: dto.x,
|
||||
boundingBoxX2: dto.x + dto.width,
|
||||
boundingBoxY1: dto.y,
|
||||
boundingBoxY2: dto.y + dto.height,
|
||||
boundingBoxX1: Math.round(topLeft.x),
|
||||
boundingBoxX2: Math.round(bottomRight.x),
|
||||
boundingBoxY1: Math.round(topLeft.y),
|
||||
boundingBoxY2: Math.round(bottomRight.y),
|
||||
sourceType: SourceType.Manual,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user