/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jmeter.save;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JComponent;

import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.xmlgraphics.image.codec.png.PNGEncodeParam;
import org.apache.xmlgraphics.image.codec.png.PNGImageEncoder;
import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder;

/**
 * Class is responsible for taking a component and saving it as a JPEG, PNG or
 * TIFF. The class is very simple. Thanks to Batik and the developers who worked
 * so hard on it.
 */
public class SaveGraphicsService {

    public static final int PNG = 0;

    public static final int TIFF = 1;

    public static final String PNG_EXTENSION = ".png"; //$NON-NLS-1$

    public static final String TIFF_EXTENSION = ".tif"; //$NON-NLS-1$

    public static final String JPEG_EXTENSION = ".jpg"; //$NON-NLS-1$

    /**
     *
     */
    public SaveGraphicsService() {
        super();
    }

    /**
     * Method will save the JComponent as an image. The formats are PNG, and
     * TIFF.
     *
     * @param filename
     *            name of the file to store the image into
     * @param type
     *            of the image to be stored. Can be one of {@value #PNG} for PNG
     *            or {@value #TIFF} for TIFF
     * @param component
     *            to draw the image on
     */
    public void saveJComponent(String filename, int type, JComponent component) {
        Dimension size = component.getSize();
        BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_BYTE_INDEXED);
        Graphics2D grp = image.createGraphics();
        component.paint(grp);

        if (type == PNG) {
            filename += PNG_EXTENSION;
            this.savePNGWithBatik(filename, image);
        } else if (type == TIFF) {
            filename = filename + TIFF_EXTENSION;
            this.saveTIFFWithBatik(filename, image);
        }
    }

    /**
     * Use Batik to save a PNG of the graph
     *
     * @param filename
     *            name of the file to store the image into
     * @param image
     *            to be stored
     */
    public void savePNGWithBatik(String filename, BufferedImage image) {
        File outfile = new File(filename);
        OutputStream fos = createFile(outfile);
        if (fos == null) {
            return;
        }
        PNGEncodeParam param = PNGEncodeParam.getDefaultEncodeParam(image);
        PNGImageEncoder encoder = new PNGImageEncoder(fos, param);
        try {
            encoder.encode(image);
        } catch (IOException e) {
            JMeterUtils.reportErrorToUser("PNGImageEncoder reported: "+e.getMessage(), "Problem creating image file");
        } finally {
            JOrphanUtils.closeQuietly(fos);
        }
    }

    /**
     * Use Batik to save a TIFF file of the graph
     *
     * @param filename
     *            name of the file to store the image into
     * @param image
     *            to be stored
     */
    public void saveTIFFWithBatik(String filename, BufferedImage image) {
        File outfile = new File(filename);
        OutputStream fos = createFile(outfile);
        if (fos == null) {
            return;
        }
        TIFFEncodeParam param = new TIFFEncodeParam();
        TIFFImageEncoder encoder = new TIFFImageEncoder(fos, param);
        try {
            encoder.encode(image);
        } catch (IOException e) {
            JMeterUtils.reportErrorToUser("TIFFImageEncoder reported: "+e.getMessage(), "Problem creating image file");
        } catch (Error e) { // NOSONAR TIFFImageEncoder uses Error to report runtime problems
            JMeterUtils.reportErrorToUser("TIFFImageEncoder reported: "+e.getMessage(), "Problem creating image file");
            if (e.getClass() != Error.class){// NOSONAR rethrow other errors
                throw e;
            }
        } finally {
            JOrphanUtils.closeQuietly(fos);
        }
    }

    /**
     * Create a new file for the graphics. Since the method creates a new file,
     * we shouldn't get a FNFE.
     *
     * @param filename
     * @return output stream created from the filename
     */
    private FileOutputStream createFile(File filename) {
        try {
            return new FileOutputStream(filename);
        } catch (FileNotFoundException e) {
            JMeterUtils.reportErrorToUser("Could not create file: "+e.getMessage(), "Problem creating image file");
            return null;
        }
    }

}

@@ -880,16 +880,54 @@
 hics2D;%0A
+import java.awt.geom.AffineTransform;%0A
 import j
@@ -1229,133 +1229,8 @@
 ls;%0A
-import org.apache.xmlgraphics.image.codec.png.PNGEncodeParam;%0Aimport org.apache.xmlgraphics.image.codec.png.PNGImageEncoder;%0A
 impo
@@ -1353,16 +1353,76 @@
 Encoder;
+%0Aimport org.apache.xmlgraphics.image.writer.ImageWriterUtil;
 %0A%0A/**%0A *
@@ -2535,24 +2535,47 @@
 .getSize();%0A
+        int scale = 2;%0A
         Buff
@@ -2620,16 +2620,24 @@
 ze.width
+ * scale
 , size.h
@@ -2641,16 +2641,24 @@
 e.height
+ * scale
 , Buffer
@@ -2674,20 +2674,15 @@
 YPE_
-BYTE_INDEXED
+INT_RGB
 );%0A 
@@ -2741,29 +2741,256 @@
     
-component.paint(grp);
+try %7B%0A            AffineTransform transform = new AffineTransform();%0A            transform.setToScale(scale, scale);%0A            grp.setTransform(transform);%0A            component.paint(grp);%0A        %7D finally %7B%0A            grp.dispose();%0A        %7D
 %0A%0A  
@@ -3588,293 +3588,70 @@
     
-OutputStream fos = createFile(outfile);%0A        if (fos == null) %7B%0A            return;%0A        %7D%0A        PNGEncodeParam param = PNGEncodeParam.getDefaultEncodeParam(image);%0A        PNGI
+try %7B%0A            ImageWriterUtil.saveAsPNG(i
 mage
-Encoder encoder = new PNGImageEncoder(fos, param);%0A        try %7B%0A            encoder.encode(imag
+, 144, outfil
 e);%0A
@@ -3807,72 +3807,8 @@
 %22);%0A
-        %7D finally %7B%0A            JOrphanUtils.closeQuietly(fos);%0A
     

Improve quality for "Save node as image" action