imagor icon indicating copy to clipboard operation
imagor copied to clipboard

[Question]: jpegtran, MozJPEG optimizers

Open rela589n opened this issue 1 year ago • 2 comments

Hi there!

I'd like to ask about imagor's available image optimization options.

In Thumbor there's particular feature that's available - jpegtran optimizer. I haven't tested it myself, but currently I seek for a tool that besides the rest of the functions would allow image size optimization and that's why I ask if there's native support from imagor, since I haven't found any mention in the README?

Also, I see that there's -vips-mozjpeg option that enables MozJPEG compression. Is it natively bundled in the docker image, or is it necessary to build a custom docker image to have this option available?

FWIK, mozjpeg seems to do a better compression, while taking more time compared to jpegtran. If possible, I would really appreciate it if you could share from your own experience what size reduction we could expect from these image optimizers.

Thank you

rela589n avatar Jul 27 '24 12:07 rela589n

If MozJPEG is being complied on host machine, -vips-mozjpeg would enable MozJPEG compression. Other it would be no effect.

MozJPEG is currently not bundled with docker image, due the default libjpeg-turbo being used by many other dependencies, and we have yet to make it work alongside with other dependencies. https://github.com/cshum/imagor/blob/master/Dockerfile

However if anyone manages to make MozJPEG complie successfully alongside all the other dependencies within the Docker image, I am all for a PR.

cshum avatar Aug 07 '24 13:08 cshum

Got it,

Thank you!

rela589n avatar Sep 07 '24 17:09 rela589n

@cshum Hey,

keep up the great work :) The attached Dockerfile installs Imagor with MozJPEG for me; leading to quite a lot smaller JPEG files as expected :)

All the best, Sebastian

# https://github.com/cshum/imagor/blob/master/Dockerfile
ARG GOLANG_VERSION=1.25.1
FROM golang:${GOLANG_VERSION}-trixie as builder

ARG VIPS_VERSION=8.17.2
ARG TARGETARCH
ARG ENABLE_MAGICK=false

ARG MOZJPEG_VERSION=4.1.1
ARG MOZJPEG_URL=https://github.com/mozilla/mozjpeg/archive


ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

ADD ${MOZJPEG_URL}/v${MOZJPEG_VERSION}.tar.gz /tmp/
WORKDIR /tmp


RUN DEBIAN_FRONTEND=noninteractive \
  apt-get update && \
  apt-get install --no-install-recommends -y  build-essential libboost-all-dev pkg-config  autoconf automake libtool nasm make cmake flex

RUN DEBIAN_FRONTEND=noninteractive \
  apt-get install --no-install-recommends -y  libpng-tools libpng-dev zlib1g-dev

RUN tar xf v${MOZJPEG_VERSION}.tar.gz \
  && cd mozjpeg-${MOZJPEG_VERSION} \
  && cmake -G"Unix Makefiles" . \
  && make -j4 \
  && make install \
  && cp jpegint.h /usr/include/jpegint.h \
  && cd .. \
  && rm -rf mozjpeg


# Installs libvips + required libraries + conditionally ImageMagick
RUN DEBIAN_FRONTEND=noninteractive \
  apt-get update && \
  apt-get install --no-install-recommends -y \
  ca-certificates \
  automake build-essential curl \
  meson ninja-build pkg-config \
  gobject-introspection gtk-doc-tools libglib2.0-dev libjpeg62-turbo-dev libpng-dev \
  libwebp-dev libtiff-dev libexif-dev libxml2-dev libpoppler-glib-dev \
  swig libpango1.0-dev libmatio-dev libopenslide-dev libcfitsio-dev libopenjp2-7-dev liblcms2-dev \
  libgsf-1-dev libfftw3-dev liborc-0.4-dev librsvg2-dev libimagequant-dev libaom-dev \
  libspng-dev libcgif-dev libheif-dev libheif-plugin-x265 libheif-plugin-aomenc libjxl-dev libavif-dev && \
  if [ "$ENABLE_MAGICK" = "true" ]; then \
    apt-get install --no-install-recommends -y libmagickwand-dev; \
  fi && \
  cd /tmp && \
    export PKG_CONFIG_PATH=/opt/mozjpeg/lib64/pkgconfig/ && \
    curl -fsSLO https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz && \
    tar xf vips-${VIPS_VERSION}.tar.xz && \
    cd vips-${VIPS_VERSION} && \
    meson setup _build \
    --buildtype=release \
    --strip \
    --prefix=/usr/local \
    --libdir=lib \
    -Dmagick=$(if [ "$ENABLE_MAGICK" = "true" ]; then echo "enabled"; else echo "disabled"; fi) \
    -Djpeg-xl=enabled \
    -Dintrospection=disabled && \
    ninja -C _build && \
    ninja -C _build install && \
  ldconfig && \
  rm -rf /usr/local/lib/libvips-cpp.* && \
  rm -rf /usr/local/lib/*.a && \
  rm -rf /usr/local/lib/*.la

ENV PKG_CONFIG_PATH=/opt/mozjpeg/lib64/pkgconfig/ \
    LD_LIBRARY_PATH=/opt/mozjpeg/lib64

WORKDIR ${GOPATH}/src/github.com/cshum/imagor


RUN git clone https://github.com/cshum/imagor .
RUN go mod download


RUN go build -o ${GOPATH}/bin/imagor ./cmd/imagor/main.go

FROM debian:trixie-slim as runtime
LABEL maintainer="[email protected]"

ARG ENABLE_MAGICK=false

COPY --from=builder /usr/local/lib /usr/local/lib
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
COPY --from=builder /opt/mozjpeg /opt/mozjpeg

ENV PKG_CONFIG_PATH=/opt/mozjpeg/lib64/pkgconfig/ \
    LD_LIBRARY_PATH=/opt/mozjpeg/lib64

# Install runtime dependencies including conditionally ImageMagick
RUN DEBIAN_FRONTEND=noninteractive \
  apt-get update && \
  apt-get install --no-install-recommends -y \
  procps curl libglib2.0-0 libjpeg62-turbo libpng16-16 libopenexr-3-1-30 \
  libwebp7 libwebpmux3 libwebpdemux2 libtiff6 libexif12 libxml2 libpoppler-glib8t64 \
  libpango-1.0-0 libmatio13 libopenslide0 libopenjp2-7 libjemalloc2 \
  libgsf-1-114 libfftw3-bin liborc-0.4-0 librsvg2-2 libcfitsio10t64 libimagequant0 libaom3 \
  libspng0 libcgif0 libheif1 libheif-plugin-x265 libheif-plugin-aomenc libjxl0.11 && \
  if [ "$ENABLE_MAGICK" = "true" ]; then \
    apt-get install --no-install-recommends -y libmagickwand-7.q16-10; \
  fi && \
  ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \
  apt-get autoremove -y && \
  apt-get autoclean && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY --from=builder /go/bin/imagor /usr/local/bin/imagor

ENV VIPS_WARNING=0
ENV MALLOC_ARENA_MAX=2
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so

ENV PORT 8000

# use unprivileged user
USER nobody

ENTRYPOINT ["/usr/local/bin/imagor"]

EXPOSE ${PORT}


skurfuerst avatar Sep 26 '25 19:09 skurfuerst

@skurfuerst I am trying to build a mozjpeg variant of imagor docker image:

docker pull ghcr.io/cshum/imagor-mozjpeg:docker-variants

https://github.com/cshum/imagor/pkgs/container/imagor-mozjpeg

Would you please help to check if this docker image has mozjpeg properly installed?

(during testing only amd64 is available, as arm64 is taking too long to build)

cshum avatar Sep 27 '25 08:09 cshum

I will try out tonight and give feedback :)

skurfuerst avatar Sep 27 '25 13:09 skurfuerst

@cshum Yeah, confirmed, quite some impressive size improvements with your built image from ghcr.io/cshum/imagor-mozjpeg:docker-variants and VIPS_MOZJPEG: 1

see this table for details:

vendor/bin/testbench  imagor:benchmark-image-sizes
+---------------------+--------+------------+----------+
| version             | format | dimensions | size     | without mozjpeg (from above)
+---------------------+--------+------------+----------+
| original            | jpeg   | orig       | 6.3 MB   |
| optimized_no_change | jpeg   | orig       | 2.5 MB   | 3.7 MB (32.4% bigger)
| optimized_quality95 | jpeg   | orig       | 10.6 MB  | 13.8 MB (23.2% bigger)
| optimized_quality80 | jpeg   | orig       | 3.1 MB   | 4.3 MB (27.9% bigger)
| optimized_quality50 | jpeg   | orig       | 1.5 MB   | 2.5 MB (40.0% bigger)
| optimized_no_change | jpeg   | 600x600    | 35.9 KB  | 44.3 KB (19.0% bigger)
| optimized_quality95 | jpeg   | 600x600    | 152.2 KB | 161.9 KB (6.0% bigger)
| optimized_quality80 | jpeg   | 600x600    | 42.8 KB  | 50.8 KB (15.7% bigger)
| optimized_quality50 | jpeg   | 600x600    | 22.1 KB  | 29.7 KB (25.6% bigger)
| optimized_no_change | webp   | orig       | 1.5 MB   |
| optimized_quality95 | webp   | orig       | 6.2 MB   |
| optimized_quality80 | webp   | orig       | 1.9 MB   |
| optimized_quality50 | webp   | orig       | 1.1 MB   |
| optimized_no_change | webp   | 600x600    | 28.6 KB  |
| optimized_quality95 | webp   | 600x600    | 97.4 KB  |
| optimized_quality80 | webp   | 600x600    | 35.6 KB  |
| optimized_quality50 | webp   | 600x600    | 20.5 KB  |
+---------------------+--------+------------+----------+

skurfuerst avatar Sep 27 '25 17:09 skurfuerst

The MozJPEG variant of Imagor Docker image is now available at v1.5.18 https://github.com/cshum/imagor#mozjpeg-support

cshum avatar Sep 27 '25 22:09 cshum