{"id":18558174,"url":"https://github.com/ghillert/image-metadata","last_synced_at":"2025-04-10T01:32:41.101Z","repository":{"id":141309099,"uuid":"504714334","full_name":"ghillert/image-metadata","owner":"ghillert","description":"Examples for processing image metadata using Java","archived":false,"fork":false,"pushed_at":"2024-09-16T10:35:26.000Z","size":6454,"stargazers_count":13,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-24T14:38:15.319Z","etag":null,"topics":["graalvm","image-processing","imagemetadata","java","spring","springboot"],"latest_commit_sha":null,"homepage":"https://medium.com/@hillert/read-write-image-metadata-with-java-part-2-9c5c0d817021","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghillert.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-18T01:25:19.000Z","updated_at":"2025-02-15T12:35:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"538206f1-c72f-4d87-8257-d807817d6b32","html_url":"https://github.com/ghillert/image-metadata","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghillert%2Fimage-metadata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghillert%2Fimage-metadata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghillert%2Fimage-metadata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghillert%2Fimage-metadata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghillert","download_url":"https://codeload.github.com/ghillert/image-metadata/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248140757,"owners_count":21054351,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graalvm","image-processing","imagemetadata","java","spring","springboot"],"created_at":"2024-11-06T21:39:07.294Z","updated_at":"2025-04-10T01:32:36.089Z","avatar_url":"https://github.com/ghillert.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":":current-version: 1.0.0-SNAPSHOT\n\n= Image Metadata processing using Java\n\nimage:https://github.com/ghillert/image-metadata/workflows/Java%20CI%20with%20Maven/badge.svg[CI Image Metadata,link=https://github.com/ghillert/image-metadata/actions]\n\nThis repository contains examples for processing image metadata using Java. Currently, the following module\nis available:\n\n- *image-metadata-commons-imaging*\n\nThis https://spring.io/projects/spring-boot[Spring Boot] 3 application will allow you to upload images (JPG, PNG, GIF)\nand the application will extract the metadata from those files using\nhttps://commons.apache.org/proper/commons-imaging/[Apache Commons Imaging]. This includes:\n\n- *EXIF* (Exchangeable image file format)\n- *IPTC* (International Press Telecommunications Council)\n- *XMP* (eXtensible Metadata Platform)\n- Generic *file* metadata\n\nTo learn more about the alphabet soup, see my blog post:\nhttps://medium.com/@hillert/read-write-image-metadata-with-java-part-1-d5e2057c80d9[Read \u0026 Write Image Metadata with Java — Part 1]\nThis demo application also provides the following additional features:\n\n- Remove all image metadata\n- Populate image metadata such as image title and reference id\n- Ability to resize images\n- Slightly sharpen resized images using a Gaussian Unsharp Mask\n- Add a font label to resized images\n- Ability to load images using ImageIO or AWT Toolkit (To study performance differences)\n- Ability to download the stored image\n\nNOTE: Image metadata is manipulated during file upload. Any other manipulation such as resizing is done during image\nretrieval. This is purely a demo app and not meant to be production ready.\n\n== UI Options\n\n=== File upload\n\nThe main input field (and only mandatory input field) is the file upload option. You can select\nany image of the following type to extract metadata from:\n\n- JPG\n- PNG\n- GIF\n\n=== Title\n\nThe title input field, will populate\n\n- the XMP `Title` tag of the Dublin Core namespace.\n- the IPTC `Object Name` field\n- the EXIF `Image Description` Field\n\nIn case you also selected the `Remove Metadata` checkbox, we will also populate the `XPTitle` EXIF tag.\n\n- https://exiftool.org/TagNames/XMP.html#dc[XMP Dublin Core (dc) namespace tags]\n- https://exiftool.org/TagNames/EXIF.html\n- https://exiftool.org/TagNames/IPTC.html#ApplicationRecord\n\n=== Reference ID\n\nPopulates the IPTC field `OriginalTransmissionReference` as well as the XMP tag `TransmissionReference`. These two fields\nare commonly used as a job identifier. So if you need to tie your images to e.g. a database record, this might be a useful\nfield to know about. For more information, please also see the following links for more information:\n\n- https://exiftool.org/TagNames/XMP.html#photoshop[XMP photoshop Tags]\n- https://exiftool.org/TagNames/IPTC.html#ApplicationRecord[IPTC ApplicationRecord Tags]\n\n=== Remove Metadata\n\nRemoves all _IPTC_, _EXIF_ and _XMP_ metadata.\n\n=== Populate Windows Tags\n\nThe following tags are the Windows-specific exif tags:\n\n- XPTitle (Populated by EXIF tag ImageDescription)\n- XPComment\n- XPAuthor (Populated by EXIF tag Artist)\n- XPKeywords\n- XPSubject\n- Rating\n- RatingPercent\n\nIf the checkbox is selected AND the Caption/Title input field is populated, we will populate the `xptitle` tag.\nPlease also see the EXIF tag documentation at https://exiftool.org/TagNames/EXIF.html.\n\n== Building from Source\n\n=== Requirements\n\n- https://git-scm.com/[Git] to clone the repository\n\n==== Standard Java\n\n- https://www.oracle.com/java/technologies/downloads/#java21[Java 21] or\n- https://www.oracle.com/java/technologies/downloads/#java17[Java 17]\n\nTIP: Use https://sdkman.io/[SDKMAN!] to install any version of Java.\n\n==== Native Compilation:\n\nFor the native compilation support, you will need a https://www.graalvm.org/[GraalVM] based implementation of Java. As\nthis application uses AWT classes, Bellsoft's https://bell-sw.com/liberica-native-image-kit/[Liberica Native Image Kit] (NIK)\nis currently (as of Oct 24, 2023) the best implementation. The following version was used for testing:\n\n- https://bell-sw.com/pages/downloads/native-image-kit/[BellSoft 23.1.r21-nik]\n\n[NOTE]\n====\nOracle GraalVM does not work on *MacOS*, yet. You will encounter a `No awt in java.library.path`. See\nhttps://github.com/oracle/graal/issues/4124 for details.\n\nIf you try, you will see an exception like the following:\n\n[source,bash,indent=0,subs=attributes]\n----\n2023-02-12T09:38:34.721-10:00 ERROR 65901 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.UnsatisfiedLinkError: no awt in java.library.path] with root cause\n\njava.lang.UnsatisfiedLinkError: no awt in java.library.path\n...\n----\n====\n\nTIP: Use https://sdkman.io/[SDKMAN!] to install GraalVM.\n\n=== Check out source code\n\nCheck out the project using https://git-scm.com/[Git]:\n\n[source,bash,indent=0]\n----\ngit clone https://github.com/ghillert/image-metadata.git\ncd image-metadata\n----\n\n=== Build\n\n[source,bash,indent=0]\n----\n./mvnw clean package\n----\n\n=== Run\n\n[source,bash,indent=0,subs=attributes]\n----\njava -jar ./image-metadata-commons-imaging/target/image-metadata-commons-imaging-{current-version}.jar\n----\n\nOpen your browser and go to http://localhost:8080/\n\n=== Build + Run in one go\n\n[source,bash,indent=0,subs=attributes]\n----\n./mvnw spring-boot:run -pl image-metadata-commons-imaging\n----\n\n== Going Native\n\nNative compilation has been a bit of a moving target when using AWT classes. Luckily, the situation is\ncontinuously improving. For instance, until recently the story on Windows was a bit more involved, requiring\nto compile the project using the *x64 Native Tools Command Prompt for VS 2022* (See the following\nhttps://medium.com/graalvm/using-graalvm-and-native-image-on-windows-10-9954dc071311[blog post]\nfor more information.)\n\nLuckily as of GraalVM for JDK 17.0.8 the situation on Windows is much improved -\nSee the following https://medium.com/graalvm/a-new-graalvm-release-and-new-free-license-4aab483692f5[blog post]\nfor details.\n\n*IMPORTANT*\n\nWhen using AWT and ImageIO classes etc. the native GraalVM Native Image metadata seems to be specific to the relevant platform.\nTherefore, you may need to rename the respective folder under\n`image-metadata-commons-imaging/src/main/resource/META-INF` to `native-image`. I provide the following folders:\n\n- native-image-linux\n- native-image-mac\n- native-image-windows\n\nAlternatively, you can run the *native-image-agent* as described under *Development* below.\n\n=== Creating a Local Native Image\n\nCreating a local image should be as easy as:\n\n[source,bash,indent=0,subs=attributes]\n----\n./mvnw clean package -DnativeCompile\n----\n\nThis shorthand system property will activate the Maven profiles:\n\n- native\n- nativeCompile\n\nSo you can also use:\n\n[source,bash,indent=0,subs=attributes]\n----\n./mvnw clean package -Pnative,nativeCompile\n----\n\nThe result (if successful) will be an executable binary at: `image-metadata-commons-imaging/target/image-metadata-commons-imaging`\n\nTIP: You can use https://upx.github.io/[Ultimate Packer for eXecutables] (UPX) to further compress the binary. E.g.\n`upx -9 image-metadata-commons-imaging/target/image-metadata-commons-imaging`\n\nNOTE: UPX is currently broken on MacOS 13. See the relevant https://github.com/upx/upx/issues/612[GitHub issue ticket]\nfor details.\n\n==== macOS\n\nAs the application uses some AWT classes for image processing, the native version for macOS will not run using Oracle\nGraalVM. There is an https://github.com/oracle/graal/issues/4124[open GitHub issue] at the GraalVM project.\n\nHowever, compilation will succeed and the application will run when using\nhttps://bell-sw.com/pages/downloads/native-image-kit/[Liberica Native Image Kit] (NIK).\n\n[source,bash]\n----\n./image-metadata-commons-imaging/target/image-metadata-commons-imaging\n----\n\n==== Windows\n\nOn Windows (With the latest version of GraalVM), things got super-easy, just compile and run:\n\n[source,bash]\n----\nimage-metadata-commons-imaging/target/image-metadata-commons-imaging.exe\n----\n\n==== Linux\n\nOnce compiled you need to provide the `java.home` to the executable. This is needed to load the font sub-system. However,\nthe contents of `java.home` just needs one file `fontconfig.properties` with the contents:\n\n[source,properties]\n----\nversion=1\nsequence.allfonts=default\n----\n\n[NOTE]\n====\nThis was previously for the Windows executable as well but seems to work now without. So maybe this may not be needed\neventually. For more information see:\n\n- https://github.com/adoptium/temurin-build/issues/693\n- https://www.jianshu.com/p/a53ae350f845?v=1669292961020\n====\n\nFor simplicity, the project provides a `fontconfig.properties` file. Therefore, once the binary is created, launch the\napplication using:\n\n[source,bash]\n----\n./image-metadata-commons-imaging/target/image-metadata-commons-imaging \\\n-Djava.home=iage-metadata-commons-imaging/src/lib/\n----\n\n[NOTE]\n====\nYou may also need to install `libfreetype6-dev`:\n\n[source,bash]\n----\napt install gcc zlib1g-dev build-essential libfreetype6-dev\n----\n\nSee also: https://github.com/graalvm/mandrel/issues/189\n====\n\n=== Docker\n\n_image-metadata-commons-imaging_ uses fonts, which on Linux requires `fontconfig` to be installed. That's why I use\n`paketobuildpacks/builder:full` and not the default `paketobuildpacks/builder:tiny`.\n\nIMPORTANT: Please make sure your Docker daemon is running.\n\n[source,bash,indent=0,subs=attributes]\n----\n./mvnw -Pnative spring-boot:build-image -pl :image-metadata-commons-imaging\ndocker run --rm -p 8080:8080 docker.io/library/image-metadata-commons-imaging:{current-version}\n----\n\n== Development\n\nWhen adding functionality, it may be necessary to run the *native-image-agent*. First build the jar with the\n`native` Maven profile:\n\n[source,bash,indent=0,subs=attributes]\n----\n./mvnw clean package -Pnative\n----\n\n[source,bash,indent=0,subs=attributes]\n----\njava -Dspring.aot.enabled=true \\\n-agentlib:native-image-agent=config-output-dir=image-metadata-commons-imaging/src/main/resources/META-INF/native-image \\\n-jar image-metadata-commons-imaging/target/image-metadata-commons-imaging-{current-version}.jar\n----\n\n== License\n\nImage Metadata is licensed under the link:LICENSE[Apache License] (ASL), Version 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghillert%2Fimage-metadata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghillert%2Fimage-metadata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghillert%2Fimage-metadata/lists"}