All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nustaq.kontraktor.apputil.ImageSaver Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
package org.nustaq.kontraktor.apputil;

import org.imgscalr.Scalr;
import org.nustaq.kontraktor.IPromise;
import org.nustaq.kontraktor.Promise;
import org.nustaq.kontraktor.util.Log;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.UUID;

public class ImageSaver {
    // 0..1
    static float DEFAULT_IMAGE_COMPRESSION_VALUE = 0.5f;

    String basePath;

    public ImageSaver(String basePath) {
        this.basePath = basePath;
    }

    public IPromise handleImage(String base64Image, String imgType, String path, Dimension targetSize) {
        IPromise prom = new Promise<>();
        Base64.Decoder decoder = Base64.getDecoder();
        int i = base64Image.indexOf(";base64");
        if (i < 0) {
            prom.reject("Not a Base64 Image");
            return prom;
        }
        String str = base64Image.substring(i + ";base64".length() + 1);
        byte[] decodedBytes;
        try {
            decodedBytes = decoder.decode(str);
            BufferedImage img = scalePreservingAspectRatioAsImage(decodedBytes, targetSize.width, targetSize.height);
            if (img == null) {
                prom.complete("Error scaling image...", null);
                return prom;
            }
            String fileEnding = validateType(imgType);
            String fileName = UUID.randomUUID().toString() + "." + fileEnding;
            String fullPath = basePath + "/" + fileName;
            boolean success = saveImage(img, fullPath);
            if (success) {
                String imageId = fileName;
                prom.complete(imageId, null);
                return prom;
            } else {
                prom.complete(null, "Image scaling incomplete ..");
                return prom;
            }
        } catch (Exception exc) {
            Log.Error(this, exc);
            prom.reject(exc.getMessage());
        }
        return prom;
    }

    protected String imageEndingByMimeType(String mimeType) {
        switch (mimeType) {
            case "image/cis-cod":
                return "cod"; //CIS-Cod-Dateien
            case "image/cmu-raster":
                return "ras"; //	CMU-Raster-Dateien
            case "image/fif":
                return "fif"; //	FIF-Dateien
            case "image/gif":
                return "gif"; //	GIF-Dateien
            case "image/ief":
                return "ief"; //	IEF-Dateien
            case "image/png":
                return "png"; //	PNG-Dateien
            case "image/tiff":
                return "tif"; //	TIFF-Dateien
            case "image/vasa":
                return "mcf"; //	Vasa-Dateien
            case "image/vnd.wap.wbmp":
                return "wbmp"; //	Bitmap-Dateien (WAP)
            case "image/jpeg":
            case "image/jpg":
                return "jpg"; //	JPEG-Dateien
            case "image/x-freehand":
                return "fhc"; //	Freehand-Dateien
            case "image/x-icon":
                return "ico"; //	Icon-Dateien (z.B. Favoriten-Icons)
            case "image/x-portable-anymap":
                return "pnm"; //	PBM Anymap Dateien
            case "image/x-portable-bitmap":
                return "pbm"; //	PBM Bitmap Dateien
            case "image/x-portable-graymap":
                return "pgm"; //	PBM Graymap Dateien
            case "image/x-portable-pixmap":
                return "ppm"; //	PBM Pixmap Dateien
            case "image/x-rgb":
                return "rgb"; //	RGB-Dateien
            case "image/x-windowdump":
                return "xwd"; //	X-Windows Dump
            case "image/x-xbitmap":
                return "xbm"; //	XBM-Dateien
            case "image/x-xpixmap":
                return "xpm"; //
            default:
                return "jpg";
        }
    }

    protected String validateType(String type) {
        if (type == null) return "jpg";
        type = type.toLowerCase();
        if (type.indexOf("/") >= 0) // its a mime type..
        {
            return imageEndingByMimeType(type);
        }
        return "jpg";
    }

    protected boolean saveImage(BufferedImage img, String fileName) {
        try {
            String ext = fileName.substring(fileName.lastIndexOf('.') + 1);
            File sized = new File(fileName);
            sized.mkdirs();
            try {
                ImageWriter writer = ImageIO.getImageWritersByFormatName(ext).next();
                ImageWriteParam writeParam = writer.getDefaultWriteParam();
                if (writeParam.canWriteCompressed()) {
                    if (writeParam.canWriteProgressive()) {
                        writeParam.setProgressiveMode(ImageWriteParam.MODE_COPY_FROM_METADATA);
                    }
                    // jdk bug forces change the color model from cymk to rgb..
                    img = convertCMYK2RGB(img);
                    // FIXME: Gif compression needs a compression type ..
                    writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                    if (!fileName.endsWith("gif")) {
                        writeParam.setCompressionQuality(DEFAULT_IMAGE_COMPRESSION_VALUE);
                    }
                }
            } catch (Exception ex) {
                Log.Error(this,ex);
            }
            ImageIO.write(img, ext, sized);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    protected BufferedImage convertCMYK2RGB(BufferedImage image) throws IOException {
        BufferedImage rgbImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        ColorConvertOp op = new ColorConvertOp(null);
        op.filter(image, rgbImage);
        return rgbImage;
    }

    protected BufferedImage bimgFromBytez(byte[] source) throws IOException {
        try (InputStream inputStream = new ByteArrayInputStream(source)) {
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            if (bufferedImage != null) {
                return bufferedImage;
            } else {
                throw new IllegalArgumentException("No ImageReader could read the provided data");
            }
        }
    }

    public BufferedImage scalePreservingAspectRatioAsImage(byte[] source, int targetW, int targetH) throws IOException {
        BufferedImage bufferedImage = bimgFromBytez(source);
        return scalePreservingAspectRatioAsImage(bufferedImage, targetW, targetH);
    }

    public BufferedImage scalePreservingAspectRatioAsImage(BufferedImage bimg, int targetW, int targetH) {
        double width = bimg.getWidth(); // Double on purpose for division
        double height = bimg.getHeight(); // Double on purpose for division
        Scalr.Mode mode = (targetW / width >= targetH / height) ? Scalr.Mode.FIT_TO_WIDTH : Scalr.Mode.FIT_TO_HEIGHT;
        bimg = Scalr.resize(bimg, Scalr.Method.QUALITY, mode, targetW, targetH);
        int scaledImageW = bimg.getWidth();
        int scaledImageH = bimg.getHeight();
        if (scaledImageH != targetH || scaledImageW != targetW) {
            if (scaledImageH > scaledImageW) {
                int startingW = (scaledImageW - targetW) / 2;
                int startingH = 0;
                bimg = bimg.getSubimage(startingW, startingH, targetW, targetH);
            } else {
                // sonst center
                int startingW = (scaledImageW - targetW) / 2;
                int startingH = (scaledImageH - targetH) / 2;
                bimg = bimg.getSubimage(startingW, startingH, targetW, targetH);
            }
        }
        return bimg;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy