Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ghillert/image-metadata
Examples for processing image metadata using Java
https://github.com/ghillert/image-metadata
graalvm image-processing imagemetadata java spring springboot
Last synced: about 2 months ago
JSON representation
Examples for processing image metadata using Java
- Host: GitHub
- URL: https://github.com/ghillert/image-metadata
- Owner: ghillert
- License: apache-2.0
- Created: 2022-06-18T01:25:19.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-25T04:19:47.000Z (6 months ago)
- Last Synced: 2024-06-25T19:35:23.512Z (6 months ago)
- Topics: graalvm, image-processing, imagemetadata, java, spring, springboot
- Language: Java
- Homepage: https://medium.com/@hillert/read-write-image-metadata-with-java-part-2-9c5c0d817021
- Size: 6.16 MB
- Stars: 12
- Watchers: 3
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE
Awesome Lists containing this project
README
:current-version: 1.0.0-SNAPSHOT
= Image Metadata processing using Java
image:https://github.com/ghillert/image-metadata/workflows/Java%20CI%20with%20Maven/badge.svg[CI Image Metadata,link=https://github.com/ghillert/image-metadata/actions]
This repository contains examples for processing image metadata using Java. Currently, the following module
is available:- *image-metadata-commons-imaging*
This https://spring.io/projects/spring-boot[Spring Boot] 3 application will allow you to upload images (JPG, PNG, GIF)
and the application will extract the metadata from those files using
https://commons.apache.org/proper/commons-imaging/[Apache Commons Imaging]. This includes:- *EXIF* (Exchangeable image file format)
- *IPTC* (International Press Telecommunications Council)
- *XMP* (eXtensible Metadata Platform)
- Generic *file* metadataTo learn more about the alphabet soup, see my blog post:
https://medium.com/@hillert/read-write-image-metadata-with-java-part-1-d5e2057c80d9[Read & Write Image Metadata with Java — Part 1]
This demo application also provides the following additional features:- Remove all image metadata
- Populate image metadata such as image title and reference id
- Ability to resize images
- Slightly sharpen resized images using a Gaussian Unsharp Mask
- Add a font label to resized images
- Ability to load images using ImageIO or AWT Toolkit (To study performance differences)
- Ability to download the stored imageNOTE: Image metadata is manipulated during file upload. Any other manipulation such as resizing is done during image
retrieval. This is purely a demo app and not meant to be production ready.== UI Options
=== File upload
The main input field (and only mandatory input field) is the file upload option. You can select
any image of the following type to extract metadata from:- JPG
- PNG
- GIF=== Title
The title input field, will populate
- the XMP `Title` tag of the Dublin Core namespace.
- the IPTC `Object Name` field
- the EXIF `Image Description` FieldIn case you also selected the `Remove Metadata` checkbox, we will also populate the `XPTitle` EXIF tag.
- https://exiftool.org/TagNames/XMP.html#dc[XMP Dublin Core (dc) namespace tags]
- https://exiftool.org/TagNames/EXIF.html
- https://exiftool.org/TagNames/IPTC.html#ApplicationRecord=== Reference ID
Populates the IPTC field `OriginalTransmissionReference` as well as the XMP tag `TransmissionReference`. These two fields
are 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
field to know about. For more information, please also see the following links for more information:- https://exiftool.org/TagNames/XMP.html#photoshop[XMP photoshop Tags]
- https://exiftool.org/TagNames/IPTC.html#ApplicationRecord[IPTC ApplicationRecord Tags]=== Remove Metadata
Removes all _IPTC_, _EXIF_ and _XMP_ metadata.
=== Populate Windows Tags
The following tags are the Windows-specific exif tags:
- XPTitle (Populated by EXIF tag ImageDescription)
- XPComment
- XPAuthor (Populated by EXIF tag Artist)
- XPKeywords
- XPSubject
- Rating
- RatingPercentIf the checkbox is selected AND the Caption/Title input field is populated, we will populate the `xptitle` tag.
Please also see the EXIF tag documentation at https://exiftool.org/TagNames/EXIF.html.== Building from Source
=== Requirements
- https://git-scm.com/[Git] to clone the repository
==== Standard Java
- https://www.oracle.com/java/technologies/downloads/#java21[Java 21] or
- https://www.oracle.com/java/technologies/downloads/#java17[Java 17]TIP: Use https://sdkman.io/[SDKMAN!] to install any version of Java.
==== Native Compilation:
For the native compilation support, you will need a https://www.graalvm.org/[GraalVM] based implementation of Java. As
this application uses AWT classes, Bellsoft's https://bell-sw.com/liberica-native-image-kit/[Liberica Native Image Kit] (NIK)
is currently (as of Oct 24, 2023) the best implementation. The following version was used for testing:- https://bell-sw.com/pages/downloads/native-image-kit/[BellSoft 23.1.r21-nik]
[NOTE]
====
Oracle GraalVM does not work on *MacOS*, yet. You will encounter a `No awt in java.library.path`. See
https://github.com/oracle/graal/issues/4124 for details.If you try, you will see an exception like the following:
[source,bash,indent=0,subs=attributes]
----
2023-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 causejava.lang.UnsatisfiedLinkError: no awt in java.library.path
...
----
====TIP: Use https://sdkman.io/[SDKMAN!] to install GraalVM.
=== Check out source code
Check out the project using https://git-scm.com/[Git]:
[source,bash,indent=0]
----
git clone https://github.com/ghillert/image-metadata.git
cd image-metadata
----=== Build
[source,bash,indent=0]
----
./mvnw clean package
----=== Run
[source,bash,indent=0,subs=attributes]
----
java -jar ./image-metadata-commons-imaging/target/image-metadata-commons-imaging-{current-version}.jar
----Open your browser and go to http://localhost:8080/
=== Build + Run in one go
[source,bash,indent=0,subs=attributes]
----
./mvnw spring-boot:run -pl image-metadata-commons-imaging
----== Going Native
Native compilation has been a bit of a moving target when using AWT classes. Luckily, the situation is
continuously improving. For instance, until recently the story on Windows was a bit more involved, requiring
to compile the project using the *x64 Native Tools Command Prompt for VS 2022* (See the following
https://medium.com/graalvm/using-graalvm-and-native-image-on-windows-10-9954dc071311[blog post]
for more information.)Luckily as of GraalVM for JDK 17.0.8 the situation on Windows is much improved -
See the following https://medium.com/graalvm/a-new-graalvm-release-and-new-free-license-4aab483692f5[blog post]
for details.*IMPORTANT*
When using AWT and ImageIO classes etc. the native GraalVM Native Image metadata seems to be specific to the relevant platform.
Therefore, you may need to rename the respective folder under
`image-metadata-commons-imaging/src/main/resource/META-INF` to `native-image`. I provide the following folders:- native-image-linux
- native-image-mac
- native-image-windowsAlternatively, you can run the *native-image-agent* as described under *Development* below.
=== Creating a Local Native Image
Creating a local image should be as easy as:
[source,bash,indent=0,subs=attributes]
----
./mvnw clean package -DnativeCompile
----This shorthand system property will activate the Maven profiles:
- native
- nativeCompileSo you can also use:
[source,bash,indent=0,subs=attributes]
----
./mvnw clean package -Pnative,nativeCompile
----The result (if successful) will be an executable binary at: `image-metadata-commons-imaging/target/image-metadata-commons-imaging`
TIP: You can use https://upx.github.io/[Ultimate Packer for eXecutables] (UPX) to further compress the binary. E.g.
`upx -9 image-metadata-commons-imaging/target/image-metadata-commons-imaging`NOTE: UPX is currently broken on MacOS 13. See the relevant https://github.com/upx/upx/issues/612[GitHub issue ticket]
for details.==== macOS
As the application uses some AWT classes for image processing, the native version for macOS will not run using Oracle
GraalVM. There is an https://github.com/oracle/graal/issues/4124[open GitHub issue] at the GraalVM project.However, compilation will succeed and the application will run when using
https://bell-sw.com/pages/downloads/native-image-kit/[Liberica Native Image Kit] (NIK).[source,bash]
----
./image-metadata-commons-imaging/target/image-metadata-commons-imaging
----==== Windows
On Windows (With the latest version of GraalVM), things got super-easy, just compile and run:
[source,bash]
----
image-metadata-commons-imaging/target/image-metadata-commons-imaging.exe
----==== Linux
Once compiled you need to provide the `java.home` to the executable. This is needed to load the font sub-system. However,
the contents of `java.home` just needs one file `fontconfig.properties` with the contents:[source,properties]
----
version=1
sequence.allfonts=default
----[NOTE]
====
This was previously for the Windows executable as well but seems to work now without. So maybe this may not be needed
eventually. For more information see:- https://github.com/adoptium/temurin-build/issues/693
- https://www.jianshu.com/p/a53ae350f845?v=1669292961020
====For simplicity, the project provides a `fontconfig.properties` file. Therefore, once the binary is created, launch the
application using:[source,bash]
----
./image-metadata-commons-imaging/target/image-metadata-commons-imaging \
-Djava.home=iage-metadata-commons-imaging/src/lib/
----[NOTE]
====
You may also need to install `libfreetype6-dev`:[source,bash]
----
apt install gcc zlib1g-dev build-essential libfreetype6-dev
----See also: https://github.com/graalvm/mandrel/issues/189
======= Docker
_image-metadata-commons-imaging_ uses fonts, which on Linux requires `fontconfig` to be installed. That's why I use
`paketobuildpacks/builder:full` and not the default `paketobuildpacks/builder:tiny`.IMPORTANT: Please make sure your Docker daemon is running.
[source,bash,indent=0,subs=attributes]
----
./mvnw -Pnative spring-boot:build-image -pl :image-metadata-commons-imaging
docker run --rm -p 8080:8080 docker.io/library/image-metadata-commons-imaging:{current-version}
----== Development
When adding functionality, it may be necessary to run the *native-image-agent*. First build the jar with the
`native` Maven profile:[source,bash,indent=0,subs=attributes]
----
./mvnw clean package -Pnative
----[source,bash,indent=0,subs=attributes]
----
java -Dspring.aot.enabled=true \
-agentlib:native-image-agent=config-output-dir=image-metadata-commons-imaging/src/main/resources/META-INF/native-image \
-jar image-metadata-commons-imaging/target/image-metadata-commons-imaging-{current-version}.jar
----== License
Image Metadata is licensed under the link:LICENSE[Apache License] (ASL), Version 2.0.