Pregunta

Mi instructor me envió este código, que se supone que es una parte integral de un proyecto en curso. Lo que pasa es que no funciona.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.Kernel;
import java.awt.image.ConvolveOp;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import javax.swing.*;


public class ImageUtil {

    public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException{

        if(quality <0||quality>1){
            throw new IllegalArgumentException ("quality has to be between 0 and 1");

        }

        ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
        Image i = ii.getImage();
        Image resizedImage = null;

        int iWidth = i.getWidth (null);
        int iHeight = i.getHeight(null);

        if (iWidth > iHeight){
            resizedImage = i.getScaledInstance(newWidth,(newWidth*iHeight)/iWidth, Image.SCALE_SMOOTH);
        } else {
            resizedImage = i.getScaledInstance((newWidth*iWidth)/iHeight,newWidth, Image.SCALE_SMOOTH);
        }

        Image temp = new ImageIcon (resizedImage).getImage();

        BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null),
                                                         BufferedImage.TYPE_INT_RGB);

        // copy to a buffered image
        Graphics g = bufferedImage.createGraphics();

        g.setColor(Color.white);
        g.fillRect(0,0,temp.getWidth(null), temp.getHeight(null)); // causea el error de ejecución?
        g.drawImage(temp,0,0,null);
        g.dispose();

        float softenFactor = 0.05f;
        float [] softenArray = {0, softenFactor,0, softenFactor, 1-(softenFactor*4), softenFactor,0, softenFactor,0};
        Kernel kernel = new Kernel (3,3,softenArray);
        ConvolveOp cOp = new ConvolveOp (kernel, ConvolveOp.EDGE_NO_OP,null);
        bufferedImage = cOp.filter (bufferedImage,null);

        FileOutputStream out = new FileOutputStream(resizedFile);

        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

        JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);

        param.setQuality(quality,true);

        encoder.setJPEGEncodeParam(param);
        encoder.encode(bufferedImage);



    }

    public static void main(String args[]) throws IOException {
       File originalImage= new File ("/images/goya.jpg");
       resize(originalImage,new File("/images/goyanuevotamanio.jpg"),350, 0.2f);
       resize(originalImage, new File("/images/goyanuevotamanio.jpg"), 350, 1f);

    }

}

Se dice que el código debe ser capaz de cambiar el tamaño de altura y anchura sin embargo, su método de cambio de tamaño:

public static void resize(File originalFile, File resizedFile, int newWidth, float quality)

carece de un parámetro newHeight.

El RuntimeException que ha arrojado dice:

Exception in thread "main" java.lang.IllegalArgumentException: **Width (-1) and height (-1) cannot be <= 0**
        at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:999)
        at java.awt.image.BufferedImage.<init>(BufferedImage.java:312)
        at ImageUtil.resize(ImageUtil.java:38)
        at ImageUtil.main(ImageUtil.java:72)
Java Result: 1

¿Cómo puedo cambiar esto?

¿Fue útil?

Solución

Sin analizar el código para ver cuál podría ser el problema, lo que puedo decir que si la intención es mantener la relación de aspecto de las imágenes, no se necesita un nuevo parámetro de altura. Siempre será una relación fija de la anchura.

ACTUALIZACIÓN:

Me he encontrado el código de mi propia imagen de prueba en contra y que en realidad funciona como se esperaba. El error que está recibiendo es muy probablemente causado cuando el programa no puede encontrar la imagen de origen que especifique. Me sale el mismo error cuando especifico una imagen de origen que no existe.

Trate de usar una ruta absoluta (incluyendo letra de la unidad, etc.) la imagen de origen para.

ACTUALIZACIÓN 2

Agregue el código siguiente después de la línea ..

ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());

if(ii.getImageLoadStatus() == MediaTracker.COMPLETE)
{
    System.out.print("Load image ok\n");
}
else
{
    System.out.print("Load image failed\n");
}

Esto le dirá si el programa está fallando para cargar la imagen de origen.

Otros consejos

¿Por qué se aplica suavizar para cambiar su tamaño tiene que ser afilar Kernel -1 -2 -1 -2 12 + q -2 -1 -2 -1 donde un típico q podría ser 28 y no se applyng la versión de cambio de tamaño de drawImage

(q = 36 es equivalente a su F = 0,05 para afilar)

A juzgar por el Seguimiento de la pila La excepción es lanzada por esta línea:

BufferedImage bufferedImage = new BufferedImage (temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

Me gustaría que esto es probablemente debido a temp.getWidth y temp.getHeight están regresando -1 porque la imagen no ha terminado de cargar.

Hay tutoriales y ejemplos para trabajar con imágenes en Java disponibles en la web. Una muestra está aquí http://snippets.dzone.com/posts/show/92. Busque el uso de ImageObserver código.

Hay que dar al programa un parámetro de inicio entre 0 y 1. Lo hice y que funcione a la perfección.

adaptar esta:

private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    double resizeWidth = srcWidth;
    double resizeHeight = srcHeight;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top