From d7c207cc525669272a22b7c4d33daac44ede9951 Mon Sep 17 00:00:00 2001 From: sharevb Date: Sun, 21 Jan 2024 15:21:03 +0100 Subject: [PATCH] feat(new tool): Image EXIF Reader - Read EXIF/IPTC/XMP and other metadata from image files - Estimate JPEG Quality factor --- package.json | 2 + pnpm-lock.yaml | 30 +++- .../image-exif-reader/image-exif-reader.vue | 155 ++++++++++++++++++ src/tools/image-exif-reader/index.ts | 12 ++ .../jpeg-quality-estimator.d.ts | 4 + src/tools/index.ts | 9 +- 6 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 src/tools/image-exif-reader/image-exif-reader.vue create mode 100644 src/tools/image-exif-reader/index.ts create mode 100644 src/tools/image-exif-reader/jpeg-quality-estimator.d.ts diff --git a/package.json b/package.json index e0148f87..90167659 100644 --- a/package.json +++ b/package.json @@ -57,11 +57,13 @@ "date-fns": "^2.29.3", "dompurify": "^3.0.6", "emojilib": "^3.0.10", + "exifreader": "^4.20.0", "figue": "^1.2.0", "fuse.js": "^6.6.2", "highlight.js": "^11.7.0", "iarna-toml-esm": "^3.0.5", "ibantools": "^4.3.3", + "jpeg-quality-estimator": "^1.0.1", "json5": "^2.2.3", "jwt-decode": "^3.1.2", "libphonenumber-js": "^1.10.28", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfacabd4..40275e48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ dependencies: emojilib: specifier: ^3.0.10 version: 3.0.10 + exifreader: + specifier: ^4.20.0 + version: 4.20.0 figue: specifier: ^1.2.0 version: 1.2.0 @@ -86,6 +89,9 @@ dependencies: ibantools: specifier: ^4.3.3 version: 4.3.3 + jpeg-quality-estimator: + specifier: ^1.0.1 + version: 1.0.1 json5: specifier: ^2.2.3 version: 2.2.3 @@ -3374,7 +3380,7 @@ packages: dependencies: '@unhead/dom': 0.5.1 '@unhead/schema': 0.5.1 - '@vueuse/shared': 10.6.1(vue@3.3.4) + '@vueuse/shared': 10.7.2(vue@3.3.4) unhead: 0.5.1 vue: 3.3.4 transitivePeerDependencies: @@ -4016,8 +4022,8 @@ packages: - vue dev: false - /@vueuse/shared@10.6.1(vue@3.3.4): - resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==} + /@vueuse/shared@10.7.2(vue@3.3.4): + resolution: {integrity: sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==} dependencies: vue-demi: 0.14.6(vue@3.3.4) transitivePeerDependencies: @@ -4025,6 +4031,13 @@ packages: - vue dev: false + /@xmldom/xmldom@0.8.10: + resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + engines: {node: '>=10.0.0'} + requiresBuild: true + dev: false + optional: true + /@zhead/schema@1.0.0-beta.13: resolution: {integrity: sha512-P1A1vRGFBhITco8Iw4/hvnDYoE/SoVrd71dW1pBFdXJb3vP+pBtoOuhbEKy0ROJGOyzQuqvFibcwzyLlWMqNiQ==} dev: false @@ -5567,6 +5580,13 @@ packages: strip-final-newline: 2.0.0 dev: true + /exifreader@4.20.0: + resolution: {integrity: sha512-C28BhOHe5svd0Jj/5DGSIXD3PnPp46gfvHN4OkRfvHYZHkcJMhxeUxlwsgJ6Yl62zlZRtmfN+9suZFg0fv4hgg==} + requiresBuild: true + optionalDependencies: + '@xmldom/xmldom': 0.8.10 + dev: false + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -6490,6 +6510,10 @@ packages: hasBin: true dev: true + /jpeg-quality-estimator@1.0.1: + resolution: {integrity: sha512-Znaq+msIqs8Gmhg9JSdDjxUAZMOwYXWIURrfluimn5u2yJ4QAEDhf0tnTMkv3ikcHJoJysG5ewxfbqUXyw/Djg==} + dev: false + /js-beautify@1.14.6: resolution: {integrity: sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==} engines: {node: '>=10'} diff --git a/src/tools/image-exif-reader/image-exif-reader.vue b/src/tools/image-exif-reader/image-exif-reader.vue new file mode 100644 index 00000000..fee8aa3b --- /dev/null +++ b/src/tools/image-exif-reader/image-exif-reader.vue @@ -0,0 +1,155 @@ + + + diff --git a/src/tools/image-exif-reader/index.ts b/src/tools/image-exif-reader/index.ts new file mode 100644 index 00000000..c9c875f7 --- /dev/null +++ b/src/tools/image-exif-reader/index.ts @@ -0,0 +1,12 @@ +import { FileInfo } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Image EXIF/Metadata/GPS/JPEG Quality reader', + path: '/image-exif-reader', + description: 'Read EXIF, IPTC, XMP, GPS and other metadata, JPEG Quality, and other infos from images files', + keywords: ['image', 'exif', 'reader', 'iptc', 'gps', 'xmp', 'jpeg', 'quality'], + component: () => import('./image-exif-reader.vue'), + icon: FileInfo, + createdAt: new Date('2024-01-09'), +}); diff --git a/src/tools/image-exif-reader/jpeg-quality-estimator.d.ts b/src/tools/image-exif-reader/jpeg-quality-estimator.d.ts new file mode 100644 index 00000000..46ccc85c --- /dev/null +++ b/src/tools/image-exif-reader/jpeg-quality-estimator.d.ts @@ -0,0 +1,4 @@ +declare module 'jpeg-quality-estimator' { + const getJpegQuality: (file: Uint8Array) => number; + export default getJpegQuality; +} diff --git a/src/tools/index.ts b/src/tools/index.ts index 52bdf8e3..d82db0c0 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -75,6 +75,7 @@ import { tool as urlParser } from './url-parser'; import { tool as uuidGenerator } from './uuid-generator'; import { tool as macAddressLookup } from './mac-address-lookup'; import { tool as xmlFormatter } from './xml-formatter'; +import { tool as imageExifReader } from './image-exif-reader'; export const toolsByCategory: ToolCategory[] = [ { @@ -124,7 +125,13 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Images and videos', - components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder], + components: [ + qrCodeGenerator, + wifiQrCodeGenerator, + svgPlaceholderGenerator, + cameraRecorder, + imageExifReader, + ], }, { name: 'Development',