Skip to content

Commit 3b9e4a5

Browse files
committed
HEIC thumbnails: add ImageMagick to release
1 parent 69aa14d commit 3b9e4a5

File tree

21 files changed

+106
-54
lines changed

21 files changed

+106
-54
lines changed

Makefile

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ IMAGE_FQIN:=asaintsever/tinyworld
99

1010
.SILENT: ; # No need for @
1111
.ONESHELL: ; # Single shell for a target (required to properly use local variables)
12-
.PHONY: help init clean format test package run-ui run-indexor pre-release gen-portableapp gen-container-image gen-appimage next-version release
12+
.PHONY: help init clean format test package run-ui run-indexor pre-release gen-portableapp gen-oci-image gen-appimage next-version release
1313
.DEFAULT_GOAL := help
1414

1515
help: ## Show Help
@@ -42,11 +42,15 @@ run-ui: ## Run TinyWorld UI
4242
mvn package -Dmaven.test.skip=true -P UI
4343

4444
pre-release:
45+
set -e
4546
mkdir -p release/artifacts
47+
chmod +x release/get-3rd-party.sh
4648
chmod +x release/release-helper.sh
4749
chmod +x release/appimage/appdir-gen.sh
4850
chmod +x release/appimage/x86_64/appimagetool-x86_64
4951
chmod +x release/portable/portableapp-gen.sh
52+
echo "Get 3rd-party software ..."
53+
release/get-3rd-party.sh
5054

5155
gen-portableapp: package pre-release ## Generate TinyWorld Portable App
5256
set -e
@@ -63,19 +67,19 @@ gen-appimage: package pre-release ## Generate TinyWorld AppImage
6367
release/appimage/appdir-gen.sh
6468
release/appimage/x86_64/appimagetool-x86_64 release/appimage/AppDir release/artifacts/TinyWorld-${RELEASE_VERSION}-x86_64.AppImage
6569

66-
gen-container-image: package pre-release ## Generate TinyWorld Container Image
70+
gen-oci-image: package pre-release ## Generate TinyWorld OCI Image
6771
set -e
68-
echo "Build container image ..."
69-
release/release-helper.sh release/docker
70-
podman build -t ${IMAGE_FQIN}:${RELEASE_VERSION} release/docker
72+
echo "Build OCI image ..."
73+
release/release-helper.sh release/oci-image
74+
release/oci-image/image-gen.sh ${IMAGE_FQIN} ${RELEASE_VERSION}
7175

7276
next-version: ## Set next version
7377
set -e
7478
read -p "Enter new TinyWorld version: " twNewVer
7579
mvn versions:set -DnewVersion=$$twNewVer
7680
echo -n $$twNewVer > VERSION
7781

78-
release: test gen-container-image gen-appimage gen-portableapp ## Release
82+
release: test gen-oci-image gen-appimage gen-portableapp ## Release
7983
read -p "Publish image (y/n)? " answer
8084
case $$answer in \
8185
y|Y ) \

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
- Geolocalize photos on virtual globe with metadata in annotations
1414
- Search & filter capabilities to easily navigate your photos (by dates, countries, ...)
1515
- Offline mode (use local cache for globe data)
16-
- Available as portable app, AppImage package and container image
16+
- Available as portable app, AppImage package and OCI image
1717

1818
## Supported Photo Formats
1919

@@ -23,9 +23,8 @@
2323

2424
## Requirements
2525

26-
- Java 11+ for portable app without JRE
2726
- Linux or WSL2 for AppImage
28-
- Docker or Podman for container image
27+
- Docker or Podman for OCI image
2928

3029
## Configuration
3130

@@ -35,7 +34,7 @@ See [TinyWorld Configuration](cfg/README.md)
3534

3635
### Using Portable App
3736

38-
Untar/Unzip downloaded portable package (several flavors available: without JRE, with Linux JRE, with Windows JRE) then run provided TinyWorld script:
37+
Untar/Unzip downloaded portable package (several flavors available: with Linux JRE, with Windows JRE) then run provided TinyWorld script:
3938

4039
```sh
4140
# On Linux
@@ -61,7 +60,7 @@ By default, 4Gb of memory is set via Xmx/Xms Java options. You can override this
6160
JAVA_OPTS="-Xmx2048m -Xms1024m" ./TinyWorld-<release version>-x86_64.AppImage
6261
```
6362

64-
### Using Container Image on Linux/WSL2
63+
### Using OCI Image on Linux/WSL2
6564

6665
```sh
6766
<docker|podman> run --rm -e DISPLAY -v "$HOME/.Xauthority:/root/.Xauthority:rw" -v "$HOME/.tinyworld:/root/.tinyworld" -v "$HOME/var/cache:/root/var/cache" --network host asaintsever/tinyworld:<release version>
@@ -92,7 +91,7 @@ In case you experience scaling issue with High DPI (such as globe not filling th
9291
- Maven 3
9392
- Java JDK 17
9493
- zip/unzip *(to generate TinyWorld portable app for Windows)*
95-
- Podman *(to generate TinyWorld container image)*
94+
- Podman *(to generate TinyWorld OCI image)*
9695
- FUSE *(to generate TinyWorld AppImage)*
9796

9897
> *On Ubuntu 22.04+, install required FUSE library using `sudo apt install libfuse2`*
@@ -114,8 +113,8 @@ make gen-portableapp
114113
# Build TinyWorld AppImage
115114
make gen-appimage
116115

117-
# Build TinyWorld container image
118-
make gen-container-image
116+
# Build TinyWorld OCI image
117+
make gen-oci-image
119118
```
120119

121120
## Releases

indexor/src/main/java/asaintsever/tinyworld/indexor/Indexor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import asaintsever.tinyworld.indexor.opensearch.ClusterClient;
3838
import asaintsever.tinyworld.indexor.opensearch.Document;
3939
import asaintsever.tinyworld.indexor.opensearch.DocumentAlreadyExistsException;
40+
import asaintsever.tinyworld.metadata.extractor.Extract;
4041
import asaintsever.tinyworld.metadata.extractor.PhotoMetadata;
4142

4243
public class Indexor implements Closeable {
@@ -137,6 +138,9 @@ public Indexor(String host, int port, String index, boolean useEmbeddedCluster,
137138
throw new RuntimeException(e);
138139
}
139140
});
141+
142+
// Check metadata extractor prerequisites
143+
Extract.checkPrerequisites();
140144
}
141145

142146
public PhotoMetadata getDefaultMetadata() {

metadata-extractor/src/main/java/asaintsever/tinyworld/metadata/extractor/Extract.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.nio.file.Paths;
3333
import java.util.ArrayList;
3434
import java.util.List;
35+
import java.util.Optional;
3536
import java.util.Set;
3637
import java.util.stream.Collectors;
3738
import java.util.stream.Stream;
@@ -75,6 +76,26 @@ public Result(int ok, int nok, int skip, List<String> errors) {
7576

7677
protected static Logger logger = LoggerFactory.getLogger(Extract.class);
7778
protected final static List<FileType> supportedFileTypes = List.of(FileType.Jpeg, FileType.Png, FileType.Heif);
79+
protected final static String imageMagickCommand = "magick";
80+
81+
public static boolean checkPrerequisites() {
82+
boolean isWindows = File.pathSeparator.equals(";");
83+
84+
// Check if ImageMagick is available in PATH or not.
85+
// ImageMagick is needed only to generate thumbnails from HEIC photos.
86+
try {
87+
Process improc = Runtime.getRuntime()
88+
.exec((isWindows ? imageMagickCommand + ".exe" : imageMagickCommand) + " -version");
89+
Optional<String> impathname = improc.info().command();
90+
logger.info("Found ImageMagick at: " + impathname.get());
91+
} catch (IOException e) {
92+
logger.warn("ImageMagick program not found: " + e.getMessage());
93+
logger.warn("Path is: " + System.getenv("PATH"));
94+
return false;
95+
}
96+
97+
return true;
98+
}
7899

79100
public static Result exploreFS(String rootDir, int depth, IPhotoProcess photoProcess) {
80101
int nb_processed_ok = 0;

metadata-extractor/src/main/java/asaintsever/tinyworld/metadata/extractor/PhotoObject.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ public PhotoObject extractMetadata(URI uri, FileType fileType, Metadata metadata
158158
GpsDirectory gpsDir = metadata.getFirstDirectoryOfType(GpsDirectory.class);
159159
if (gpsDir != null) {
160160
this.metadata.setGpsLatLong(gpsDir.getGeoLocation() != null
161-
? gpsDir.getGeoLocation().getLatitude() + "," + gpsDir.getGeoLocation().getLongitude() : null);
161+
? gpsDir.getGeoLocation().getLatitude() + "," + gpsDir.getGeoLocation().getLongitude()
162+
: null);
162163

163164
GpsDescriptor gpsDesc = new GpsDescriptor(gpsDir);
164165
this.metadata.setGpsDatum(gpsDesc.getDescription(GpsDirectory.TAG_MAP_DATUM));
@@ -214,8 +215,7 @@ public PhotoObject extractThumbnail(URI uri, FileType fileType, Metadata metadat
214215
// Test if HEIF format: Java Image I/O API does not support it
215216
// Make use of ImageMagick to generate a thumbnail (JPG format)
216217
if (fileType == FileType.Heif) {
217-
ImageCommand cmd = new ImageCommand("magick");
218-
// cmd.setSearchPath(""); //In case magick binary is not in path
218+
ImageCommand cmd = new ImageCommand(Extract.imageMagickCommand);
219219
Stream2BufferedImage s2b = new Stream2BufferedImage();
220220
cmd.setOutputConsumer(s2b);
221221

metadata-extractor/src/test/java/asaintsever/tinyworld/metadata/extractor/ExtractMetadataFromPhotoTest.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,14 @@
3737
import asaintsever.tinyworld.metadata.extractor.Extract.Result;
3838

3939
public class ExtractMetadataFromPhotoTest {
40-
40+
4141
static boolean isImageMagickInPath;
4242

43-
4443
@BeforeAll
4544
public static void setup() {
4645
// Check if ImageMagick is available in PATH or not.
4746
// ImageMagick is needed only to generate thumbnails from HEIC photos.
48-
try {
49-
Runtime.getRuntime().exec("magick -version");
50-
} catch (IOException e) {
51-
isImageMagickInPath = false;
52-
return;
53-
}
54-
55-
isImageMagickInPath = true;
47+
isImageMagickInPath = Extract.checkPrerequisites();
5648
}
5749

5850
@Test

release/appimage/appdir-gen.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ cp release/appimage/x86_64/AppRun-x86_64 release/appimage/AppDir/AppRun
1616
chmod +x release/appimage/AppDir/AppRun
1717
chmod +x release/appimage/AppDir/usr/bin/tinyworld.sh
1818

19+
# Include 3rd party software
20+
cp release/tmp/3rd/LICENSE-3RD-PARTY.txt release/appimage/AppDir/usr/bin
21+
cp release/tmp/3rd/linux/* release/appimage/AppDir/usr/bin
22+
1923
# Add JRE 17
2024
curl -s -L --create-dirs --output release/tmp/jre_linux.tar.gz https://github.com/asaintsever/tinyworld-utils/releases/download/jre-distro/OpenJDK17U-jre_x64_linux_hotspot_17.0.3_7.tar.gz
2125
tar -xzf release/tmp/jre_linux.tar.gz -C release/appimage/AppDir/usr/bin

release/get-3rd-party.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# clean
6+
rm -rf release/tmp/3rd || true
7+
8+
mkdir -p release/tmp/3rd/linux
9+
mkdir -p release/tmp/3rd/windows
10+
11+
# Generate 3rd-party license
12+
touch "release/tmp/3rd/LICENSE-3RD-PARTY.txt"
13+
echo -e "\n\n=====\nLicense for ImageMagick <https://imagemagick.org/>\n=====\n\n" >> "release/tmp/3rd/LICENSE-3RD-PARTY.txt"
14+
curl -s -L https://raw.githubusercontent.com/asaintsever/tinyworld-utils/main/ImageMagick-LICENSE >> "release/tmp/3rd/LICENSE-3RD-PARTY.txt"
15+
16+
# Get 3rd-party software
17+
curl -s -L --output release/tmp/3rd/linux/magick https://github.com/asaintsever/tinyworld-utils/releases/download/imagemagick-heic/magick
18+
chmod +x release/tmp/3rd/linux/magick
19+
20+
curl -s -L --output release/tmp/3rd/windows/magick.exe https://github.com/asaintsever/tinyworld-utils/releases/download/imagemagick-heic/magick.exe
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ RUN mkdir -p /opt/tinyworld
66

77
WORKDIR /opt/tinyworld
88

9-
COPY tinyworld.sh .
9+
ENV PATH=/opt/tinyworld/tools:$PATH
10+
11+
COPY tmp/magick ./tools/magick
12+
COPY tmp/LICENSE* .
1013
COPY tmp/deps ./deps
14+
COPY tinyworld.sh .
1115
COPY tmp/config ./config
1216
COPY tmp/*.jar .
1317

18+
RUN chmod +x ./tools/magick
1419
RUN chmod +x tinyworld.sh
1520

1621
CMD ["./tinyworld.sh"]

0 commit comments

Comments
 (0)