Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ bin/

imaginary
bin/imaginary
coverage.out
70 changes: 49 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
ARG GOLANG_VERSION=1.17
FROM golang:${GOLANG_VERSION}-bullseye AS builder
# syntax=docker/dockerfile:1.4

ARG GOLANG_VERSION=1.25
FROM golang:${GOLANG_VERSION}-bullseye as builder


ARG IMAGINARY_VERSION=dev
ARG LIBVIPS_VERSION=8.12.2
ARG GOLANGCILINT_VERSION=1.29.0
ARG LIBVIPS_VERSION=8.14.1
ARG GOLANGCILINT_VERSION=1.51.1

ENV LIBSPNG_VERSION="0.7.3"
ENV LIBSPNG_URL="https://github.com/randy408/libspng/archive/refs/tags/v${LIBSPNG_VERSION}.tar.gz"

#ENV PDFIUM_VERSION="5579"
#ENV PDFIUM_URL="https://github.com/bblanchon/pdfium-binaries/releases/download/chromium/${PDFIUM_VERSION}/pdfium-linux-arm64.tgz"
#
## Installs libvips + required libraries
#COPY <<EOF /usr/lib/pkgconfig/pdfium.pc
#prefix=/usr
#exec_prefix=\${prefix}
#includedir=\${prefix}/include
#libdir=\${exec_prefix}/lib/aarch64-linux-gnu
#
#Name: pdfium
#Description: pdfium
#Version: ${PDFIUM_VERSION}
#Cflags: -I\${includedir}
#Libs: -L\${libdir} -lpdfium
#EOF

# Installs libvips + required libraries
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && \
apt-get install --no-install-recommends -y \
ca-certificates \
automake build-essential curl \
automake build-essential curl meson scons file \
gobject-introspection gtk-doc-tools libglib2.0-dev libjpeg62-turbo-dev libpng-dev \
libwebp-dev libtiff5-dev libgif-dev libexif-dev libxml2-dev libpoppler-glib-dev \
swig libmagickwand-dev libpango1.0-dev libmatio-dev libopenslide-dev libcfitsio-dev \
libgsf-1-dev fftw3-dev liborc-0.4-dev librsvg2-dev libimagequant-dev libheif-dev && \
libgsf-1-dev fftw3-dev liborc-0.4-dev librsvg2-dev libimagequant-dev libheif-dev \
libexpat1-dev libgirepository1.0-dev libglib2.0-dev liblcms2-dev libnifti2-dev libniftiio-dev libopenexr-dev \
libopenjp2-7-dev patchelf pkg-config && \
cd /tmp && \
curl -fsSLO https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.gz && \
tar zvxf vips-${LIBVIPS_VERSION}.tar.gz && \
curl -L "${LIBSPNG_URL}" | tar -xzf- && \
cd /tmp/libspng-${LIBSPNG_VERSION} && \
meson build --buildtype=release && \
cd /tmp/libspng-${LIBSPNG_VERSION}/build && \
ninja && ninja install && \
# cd /usr && \
# curl -L "${PDFIUM_URL}" | tar -xzf- && \
cd /tmp && \
curl -fsSLO https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.xz && \
tar xJf vips-${LIBVIPS_VERSION}.tar.xz && \
cd /tmp/vips-${LIBVIPS_VERSION} && \
CFLAGS="-g -O3" CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 -g -O3" \
./configure \
--disable-debug \
--disable-dependency-tracking \
--disable-introspection \
--disable-static \
--enable-gtk-doc-html=no \
--enable-gtk-doc=no \
--enable-pyvips8=no && \
make && \
make install && \
CFLAGS="-g -O3" CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 -g -O3" meson setup build-dir --buildtype=release && \
cd /tmp/vips-${LIBVIPS_VERSION}/build-dir && \
CFLAGS="-g -O3" CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 -g -O3" meson compile && \
CFLAGS="-g -O3" CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0 -g -O3" meson install && \
ldconfig

# Installing golangci-lint
Expand Down Expand Up @@ -81,7 +106,8 @@ RUN DEBIAN_FRONTEND=noninteractive \
procps libglib2.0-0 libjpeg62-turbo libpng16-16 libopenexr25 \
libwebp6 libwebpmux3 libwebpdemux2 libtiff5 libgif7 libexif12 libxml2 libpoppler-glib8 \
libmagickwand-6.q16-6 libpango1.0-0 libmatio11 libopenslide0 libjemalloc2 \
libgsf-1-114 fftw3 liborc-0.4-0 librsvg2-2 libcfitsio9 libimagequant0 libheif1 && \
libgsf-1-114 fftw3 liborc-0.4-0 librsvg2-2 libcfitsio9 libimagequant0 libheif1 \
liblcms2-2 libopenexr25 libopenjp2-7 libnifti2-2 libniftiio2 && \
ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \
apt-get autoremove -y && \
apt-get autoclean && \
Expand All @@ -95,6 +121,8 @@ ENV PORT=9000
# Drop privileges for non-UID mapped environments
USER nobody

VOLUME /config

# Run the entrypoint command by default when the container starts.
ENTRYPOINT ["/usr/local/bin/imaginary"]

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ Image measures are always in pixels, unless otherwise indicated.
- **areawidth** `int` - Height area to extract. Example: `300`
- **areaheight** `int` - Width area to extract. Example: `300`
- **quality** `int` - JPEG image quality between 1-100. Defaults to `80`
- **speed** `int` - Defines the AVIF encoders CPU effort. Valid values are 0-8. Default `0`
- **compression** `int` - PNG compression level. Default: `6`
- **palette** `bool` - Enable 8-bit quantisation. Works with only PNG images. Default: `false`
- **rotate** `int` - Image rotation angle. Must be multiple of `90`. Example: `180`
Expand Down
34 changes: 22 additions & 12 deletions controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func determineAcceptMimeType(accept string) string {
switch mediaType {
case "image/webp":
return "webp"
// case "image/avif":
// return "avif"
case "image/png":
return "png"
case "image/jpeg":
Expand All @@ -92,6 +94,11 @@ func imageHandler(w http.ResponseWriter, r *http.Request, buf []byte, operation
}
}

// Use magick to process bmp image
if mimeType == "image/bmp" {
mimeType = "image/magick"
}

// Infer text/plain responses as potential SVG image
if strings.Contains(mimeType, "text/plain") && len(buf) > 8 {
if bimg.IsSVGImage(buf) {
Expand Down Expand Up @@ -136,28 +143,31 @@ func imageHandler(w http.ResponseWriter, r *http.Request, buf []byte, operation
}

image, err := operation.Run(buf, opts)

// Ensure the Vary header is set when an error occurs
if vary != "" {
w.Header().Set("Vary", vary)
}

if err != nil {
// Ensure the Vary header is set when an error occurs
if vary != "" {
w.Header().Set("Vary", vary)
}
ErrorReply(r, w, NewError("Error while processing the image: "+err.Error(), http.StatusBadRequest), o)
return
}

// Expose Content-Length response header
w.Header().Set("Content-Length", strconv.Itoa(len(image.Body)))
w.Header().Set("Content-Type", image.Mime)
if image.Mime != "application/json" && o.ReturnSize {
meta, err := bimg.Metadata(image.Body)
if err == nil {
w.Header().Set("Image-Width", strconv.Itoa(meta.Size.Width))
w.Header().Set("Image-Height", strconv.Itoa(meta.Size.Height))
if image.Mime != "application/json" {
if o.ReturnSize {
meta, err := bimg.Metadata(image.Body)
if err == nil {
w.Header().Set("Image-Width", strconv.Itoa(meta.Size.Width))
w.Header().Set("Image-Height", strconv.Itoa(meta.Size.Height))
}
}
w.Header().Set("X-Compression-Rate", fmt.Sprintf(`%.2f`, float64(len(image.Body))/float64(len(buf))))
}
if vary != "" {
w.Header().Set("Vary", vary)
}

_, _ = w.Write(image.Body)
}

Expand Down
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (e Error) HTTPCode() int {
}

func NewError(err string, code int) Error {
err = strings.Replace(err, "\n", "", -1)
err = strings.ReplaceAll(err, "\n", "")
return Error{Message: err, Code: code}
}

Expand Down
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module github.com/h2non/imaginary
go 1.12

require (
github.com/h2non/bimg v1.1.7
github.com/h2non/filetype v1.1.0
github.com/rs/cors v0.0.0-20170727213201-7af7a1e09ba3
github.com/throttled/throttled/v2 v2.15.0
github.com/h2non/bimg v1.1.9
github.com/h2non/filetype v1.1.3
github.com/rs/cors v1.11.1
gopkg.in/throttled/throttled.v2 v2.15.0
)

replace gopkg.in/throttled/throttled.v2 v2.9.1 => github.com/throttled/throttled/v2 v2.9.1
Loading