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

com.codename1.ui.util.ImageIO Maven / Gradle / Ivy

There is a newer version: 7.0.164
Show newest version
/*
 * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */
package com.codename1.ui.util;

import com.codename1.io.FileSystemStorage;
import com.codename1.io.Util;
import com.codename1.ui.Display;
import com.codename1.ui.EncodedImage;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.geom.Dimension;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Enable simple operations on image file & image objects such as dynamic scaling
 * and storage to binary formats such as JPEG. Use Display.getImageIO() to get an instance
 * of this class.
 *
 * @author Shai Almog
 */
public abstract class ImageIO {
    /**
     * Indicates the JPEG output format
     */
    public static final String FORMAT_JPEG = "jpeg";

    /**
     * Indicates the PNG output format
     */
    public static final String FORMAT_PNG = "png";
    
    /**
     * Saves an image file at the given resolution, scaling if necessary
     * 
     * @param image source image stream
     * @param response resulting image output will be written to this stream
     * @param format the format for the image either FORMAT_PNG or FORMAT_JPEG
     * @param width the width for the resulting image, use -1 to not scale
     * @param height the height of the resulting image, use -1 to not scale
     * @param quality the quality for the resulting image output (applicable mostly for JPEG), a value between 0 and 1 notice that
     * this isn't implemented in all platforms.
     */
    public abstract void save(InputStream image, OutputStream response, String format, int width, int height, float quality) throws IOException;
    
    /**
     * Saves an image object to the given format
     * 
     * @param img the image object
     * @param response resulting image output will be written to this stream
     * @param format the format for the image either FORMAT_PNG or FORMAT_JPEG
     * @param quality the quality for the resulting image output (applicable mostly for JPEG), a value between 0 and 1 notice that
     * this isn't implemented in all platforms.
     */
    public void save(Image img, OutputStream response, String format, float quality) throws IOException {
        if(img instanceof EncodedImage) {
            EncodedImage i = (EncodedImage)img;
            save(new ByteArrayInputStream(i.getImageData()), response, format, i.getWidth(), i.getHeight(), quality);
        } else {
            if(img.getImage() == null) {
                Image img2 = Image.createImage(img.getWidth(), img.getHeight(), 0);
                Graphics g = img2.getGraphics();
                g.drawImage(img, 0, 0);
                saveImage(img2, response, format, quality);
            } else {
                saveImage(img, response, format, quality);
            }
        }
    }

    /**
     * Saves an image file at the given resolution, scaling if necessary
     * 
     * @param imageFilePath the image file path
     * @param response resulting image output will be written to this stream
     * @param format the format for the image either FORMAT_PNG or FORMAT_JPEG
     * @param width the width for the resulting image, use -1 to not scale
     * @param height the height of the resulting image, use -1 to not scale
     * @param quality the quality for the resulting image output (applicable mostly for JPEG), a value between 0 and 1 notice that
     * this isn't implemented in all platforms.
     */
    public void save(String imageFilePath, OutputStream response, String format, int width, int height, float quality) throws IOException{
        InputStream in = FileSystemStorage.getInstance().openInputStream(imageFilePath);
        save(in, response, format, width, height, quality); 
        Util.cleanup(in);
    }

    /**
     * Returns the image size in pixels
     * @param imageFilePath the path to the image
     * @return the size in pixels
     */
    public Dimension getImageSize(String imageFilePath) throws IOException {
        Image img = Image.createImage(imageFilePath);
        Dimension d = new Dimension(img.getWidth(), img.getHeight());
        img.dispose();
        return d;
    }
    
    /**
     * Scales an image on disk while maintaining an aspect ratio, the appropriate aspect size will be 
     * picked based on the status of scaleToFill
     * @param imageFilePath the path to the image
     * @param preferredOutputPath the url where the image will be saved
     * @param format the format for the image either FORMAT_JPEG or FORMAT_PNG
     * @param width the desired width, either width or height will be respected based on aspect dimensions 
     * @param height the desired height, either width or height will be respected based on aspect dimensions
     * @param quality the quality for the resulting image output (applicable mostly for JPEG), a value between 0 and 1 notice that
     * this isn't implemented in all platforms.
     * @param onlyDownscale will not scale if the resolution to scale will be higher in this case will return the imageFilePath
     * @param scaleToFill when set to true will pick the larger value so the resulting image will be at least as big as width x height, when set to false
     * will create an image that is no bigger than width x height
     * @return the url for the scaled image or the url of the unscaled image
     * @throws IOException if the operation fails
     */
    public String saveAndKeepAspect(String imageFilePath, String preferredOutputPath, String format, int width, int height, float quality, boolean onlyDownscale, boolean scaleToFill) throws IOException{
        Dimension d = getImageSize(imageFilePath);
        if(onlyDownscale) {
            if(scaleToFill) {
                if(d.getHeight() <= height || d.getWidth() <= width) {
                    return imageFilePath;
                }
            } else {
                if(d.getHeight() <= height && d.getWidth() <= width) {
                    return imageFilePath;
                }
            }
        }
        
        float ratio = ((float)d.getWidth()) / ((float)d.getHeight());
        int heightBasedOnWidth = (int)(((float)width) / ratio);
        int widthBasedOnHeight = (int)(((float)height) * ratio);
        if(scaleToFill) {
            if(heightBasedOnWidth >= width) {
                height = heightBasedOnWidth;
            } else {
                width = widthBasedOnHeight;
            }
        } else {
            if(heightBasedOnWidth > width) {
                width = widthBasedOnHeight;
            } else {
                height = heightBasedOnWidth;
            }
        }
        OutputStream im = FileSystemStorage.getInstance().openOutputStream(preferredOutputPath);
        save(imageFilePath, im, format, width, height, quality);
        return preferredOutputPath;
    }
    
    /**
     * Saves an image object to the given format
     * 
     * @param img the image object
     * @param response resulting image output will be written to this stream
     * @param format the format for the image either FORMAT_PNG or FORMAT_JPEG
     * @param quality the quality for the resulting image output (applicable mostly for JPEG), a value between 0 and 1 notice that
     * this isn't implemented in all platforms.
     */
    protected abstract void saveImage(Image img, OutputStream response, String format, float quality) throws IOException;
    
    /**
     * Indicates if the given format for output is supported by this implementation
     * 
     * @param format the format for the image either FORMAT_PNG or FORMAT_JPEG
     * @return true if supported
     */
    public abstract boolean isFormatSupported(String format);
    
    
    /**
     * Gets the ImageIO instance 
     * 
     * @return the image IO instance or null if image IO isn't supported for the 
     * given platform
     */
    public static ImageIO getImageIO(){
        return Display.getInstance().getImageIO();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy