001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 */
020package org.nuxeo.ecm.platform.picture.magick.utils;
021
022import static org.nuxeo.ecm.platform.picture.api.ImagingConvertConstants.JPEG_CONVERSATION_FORMAT;
023
024import java.awt.Point;
025import java.io.File;
026
027import org.nuxeo.ecm.platform.commandline.executor.api.CmdParameters;
028import org.nuxeo.ecm.platform.commandline.executor.api.CommandException;
029import org.nuxeo.ecm.platform.commandline.executor.api.CommandLineExecutorService;
030import org.nuxeo.ecm.platform.commandline.executor.api.CommandNotAvailable;
031import org.nuxeo.ecm.platform.commandline.executor.api.ExecResult;
032import org.nuxeo.ecm.platform.picture.api.ImageInfo;
033import org.nuxeo.ecm.platform.picture.magick.MagickExecutor;
034import org.nuxeo.runtime.api.Framework;
035
036/**
037 * Unit command to extract a simplified view of a JPEG file using ImageMagick = extract the needed picture information
038 * to reach the target definition level
039 *
040 * @author tiry
041 */
042public class ImageResizer extends MagickExecutor {
043
044    /**
045     * @since 10.3
046     */
047    public static final int MAX_JEPG_DIMENSION = 65500;
048
049    public static ImageInfo resize(String inputFile, String outputFile, int targetWidth, int targetHeight,
050            int targetDepth) throws CommandNotAvailable, CommandException {
051        if (targetDepth == -1) {
052            targetDepth = ImageIdentifier.getInfo(inputFile).getDepth();
053        }
054        CommandLineExecutorService cles = Framework.getService(CommandLineExecutorService.class);
055        CmdParameters params = cles.getDefaultCmdParameters();
056        params.addNamedParameter("targetWidth", String.valueOf(targetWidth));
057        params.addNamedParameter("targetHeight", String.valueOf(targetHeight));
058        params.addNamedParameter("inputFilePath", inputFile);
059        params.addNamedParameter("outputFilePath", outputFile);
060        params.addNamedParameter("targetDepth", String.valueOf(targetDepth));
061        String commandName = "resizer";
062        // hack to manage jpeg default background
063        if (outputFile.endsWith(JPEG_CONVERSATION_FORMAT)) {
064            commandName = "jpegResizer";
065            Point size = scaleToMax(targetWidth, targetHeight, MAX_JEPG_DIMENSION);
066            params.addNamedParameter("targetWidth", String.valueOf(size.getX()));
067            params.addNamedParameter("targetHeight", String.valueOf(size.getY()));
068        }
069        ExecResult res = cles.execCommand(commandName, params);
070        if (!res.isSuccessful()) {
071            throw res.getError();
072        }
073        if (new File(outputFile).exists()) {
074            return ImageIdentifier.getInfo(outputFile);
075        } else {
076            return null;
077        }
078    }
079
080    /**
081     * Adapts width and height to a max conserving ratio.
082     *
083     * @since 10.3
084     * @return new Point to scale or the original one if none is > max.
085     */
086    public static Point scaleToMax(int width, int height, int max) {
087        if (max > 0 && (width > max || height > max)) {
088            float maxSide = Math.max(width, height);
089            float ratio = maxSide / max;
090            return new Point(Math.round(width / ratio), Math.round(height / ratio));
091        }
092        return new Point(width, height);
093    }
094
095}