diff --git a/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart b/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart index f7fa863dde..bdeab2be32 100644 --- a/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart +++ b/mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart @@ -188,7 +188,7 @@ class ExifBottomSheet extends HookConsumerWidget { ), ), subtitle: Text( - "ƒ/${exifInfo.fNumber} 1/${(1 / (exifInfo.exposureTime ?? 1)).toStringAsFixed(0)} ${exifInfo.focalLength} mm ISO${exifInfo.iso} ", + "ƒ/${exifInfo.fNumber} ${exifInfo.exposureTime} ${exifInfo.focalLength} mm ISO${exifInfo.iso} ", ), ), ], diff --git a/mobile/openapi/doc/ExifResponseDto.md b/mobile/openapi/doc/ExifResponseDto.md index af4bb349ec..3cea9375b4 100644 --- a/mobile/openapi/doc/ExifResponseDto.md +++ b/mobile/openapi/doc/ExifResponseDto.md @@ -22,7 +22,7 @@ Name | Type | Description | Notes **fNumber** | **num** | | [optional] **focalLength** | **num** | | [optional] **iso** | **num** | | [optional] -**exposureTime** | **num** | | [optional] +**exposureTime** | **String** | | [optional] **latitude** | **num** | | [optional] **longitude** | **num** | | [optional] **city** | **String** | | [optional] diff --git a/mobile/openapi/lib/model/exif_response_dto.dart b/mobile/openapi/lib/model/exif_response_dto.dart index 8423aa56a7..6c80667d5d 100644 --- a/mobile/openapi/lib/model/exif_response_dto.dart +++ b/mobile/openapi/lib/model/exif_response_dto.dart @@ -63,7 +63,7 @@ class ExifResponseDto { num? iso; - num? exposureTime; + String? exposureTime; num? latitude; @@ -273,9 +273,7 @@ class ExifResponseDto { iso: json[r'iso'] == null ? null : num.parse(json[r'iso'].toString()), - exposureTime: json[r'exposureTime'] == null - ? null - : num.parse(json[r'exposureTime'].toString()), + exposureTime: mapValueOfType(json, r'exposureTime'), latitude: json[r'latitude'] == null ? null : num.parse(json[r'latitude'].toString()), diff --git a/mobile/openapi/test/exif_response_dto_test.dart b/mobile/openapi/test/exif_response_dto_test.dart index a7ee8c52ec..8d38e88e08 100644 --- a/mobile/openapi/test/exif_response_dto_test.dart +++ b/mobile/openapi/test/exif_response_dto_test.dart @@ -86,7 +86,7 @@ void main() { // TODO }); - // num exposureTime + // String exposureTime test('to test the property `exposureTime`', () async { // TODO }); diff --git a/server/apps/microservices/src/processors/metadata-extraction.processor.ts b/server/apps/microservices/src/processors/metadata-extraction.processor.ts index b409e6af07..7e6e9dadd7 100644 --- a/server/apps/microservices/src/processors/metadata-extraction.processor.ts +++ b/server/apps/microservices/src/processors/metadata-extraction.processor.ts @@ -154,13 +154,6 @@ export class MetadataExtractionProcessor { return exifDate.toDate(); }; - const getExposureTimeDenominator = (exposureTime: string | undefined) => { - if (!exposureTime) return null; - - const exposureTimeSplit = exposureTime.split('/'); - return exposureTimeSplit.length === 2 ? parseInt(exposureTimeSplit[1]) : null; - }; - const createdAt = exifToDate(exifData?.DateTimeOriginal ?? exifData?.CreateDate ?? asset.createdAt); const modifyDate = exifToDate(exifData?.ModifyDate ?? asset.modifiedAt); const fileStats = fs.statSync(asset.originalPath); @@ -174,7 +167,7 @@ export class MetadataExtractionProcessor { newExif.model = exifData?.Model || null; newExif.exifImageHeight = exifData?.ExifImageHeight || exifData?.ImageHeight || null; newExif.exifImageWidth = exifData?.ExifImageWidth || exifData?.ImageWidth || null; - newExif.exposureTime = getExposureTimeDenominator(exifData?.ExposureTime); + newExif.exposureTime = exifData?.ExposureTime || null; newExif.orientation = exifData?.Orientation?.toString() || null; newExif.dateTimeOriginal = createdAt; newExif.modifyDate = modifyDate; diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json index 73aba74a58..ca2277dec9 100644 --- a/server/immich-openapi-specs.json +++ b/server/immich-openapi-specs.json @@ -3207,7 +3207,7 @@ "default": null }, "exposureTime": { - "type": "number", + "type": "string", "nullable": true, "default": null }, diff --git a/server/libs/domain/src/asset/response-dto/exif-response.dto.ts b/server/libs/domain/src/asset/response-dto/exif-response.dto.ts index 0dd97a3111..1695157af5 100644 --- a/server/libs/domain/src/asset/response-dto/exif-response.dto.ts +++ b/server/libs/domain/src/asset/response-dto/exif-response.dto.ts @@ -19,7 +19,7 @@ export class ExifResponseDto { fNumber?: number | null = null; focalLength?: number | null = null; iso?: number | null = null; - exposureTime?: number | null = null; + exposureTime?: string | null = null; latitude?: number | null = null; longitude?: number | null = null; city?: string | null = null; diff --git a/server/libs/domain/test/fixtures.ts b/server/libs/domain/test/fixtures.ts index f5d622fcc4..3f267f4274 100644 --- a/server/libs/domain/test/fixtures.ts +++ b/server/libs/domain/test/fixtures.ts @@ -22,7 +22,7 @@ const assetInfo: ExifResponseDto = { fNumber: 100, focalLength: 100, iso: 100, - exposureTime: 100, + exposureTime: '1/16', latitude: 100, longitude: 100, city: 'city', @@ -349,7 +349,7 @@ export const sharedLinkStub = { fNumber: 100, focalLength: 100, iso: 100, - exposureTime: 100, + exposureTime: '1/16', fps: 100, asset: null as any, exifTextSearchableColumn: '', diff --git a/server/libs/infra/src/db/entities/exif.entity.ts b/server/libs/infra/src/db/entities/exif.entity.ts index a086260147..a78323f5ad 100644 --- a/server/libs/infra/src/db/entities/exif.entity.ts +++ b/server/libs/infra/src/db/entities/exif.entity.ts @@ -72,8 +72,8 @@ export class ExifEntity { @Column({ type: 'integer', nullable: true }) iso!: number | null; - @Column({ type: 'float', nullable: true }) - exposureTime!: number | null; + @Column({ type: 'varchar', nullable: true }) + exposureTime!: string | null; /* Video info */ @Column({ type: 'float8', nullable: true }) diff --git a/server/libs/infra/src/db/migrations/1674757936889-AlterExifExposureTimeToString.ts b/server/libs/infra/src/db/migrations/1674757936889-AlterExifExposureTimeToString.ts new file mode 100644 index 0000000000..de21e180b7 --- /dev/null +++ b/server/libs/infra/src/db/migrations/1674757936889-AlterExifExposureTimeToString.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AlterExifExposureTimeToString1674757936889 implements MigrationInterface { + name = 'AlterExifExposureTimeToString1674757936889' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "exposureTime"`); + await queryRunner.query(`ALTER TABLE "exif" ADD "exposureTime" character varying`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "exposureTime"`); + await queryRunner.query(`ALTER TABLE "exif" ADD "exposureTime" double precision`); + } + +} diff --git a/web/src/api/open-api/api.ts b/web/src/api/open-api/api.ts index f3309115f0..9bacb5d165 100644 --- a/web/src/api/open-api/api.ts +++ b/web/src/api/open-api/api.ts @@ -1116,10 +1116,10 @@ export interface ExifResponseDto { 'iso'?: number | null; /** * - * @type {number} + * @type {string} * @memberof ExifResponseDto */ - 'exposureTime'?: number | null; + 'exposureTime'?: string | null; /** * * @type {number} diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index 59c0c95348..7e57158705 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -152,7 +152,7 @@

{`ƒ/${asset.exifInfo.fNumber.toLocaleString(locale)}` || ''}

{#if asset.exifInfo.exposureTime} -

{`1/${asset.exifInfo.exposureTime}`}

+

{`${asset.exifInfo.exposureTime}`}

{/if} {#if asset.exifInfo.focalLength}