Как заставить этот код для функции image resize() работать

StackOverflow https://stackoverflow.com/questions/764794

  •  12-09-2019
  •  | 
  •  

Вопрос

Мой инструктор прислал мне этот код, который должен быть неотъемлемой частью текущего проекта.Дело в том, что это не работает.

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);

    }

}

Он говорит, что код должен иметь возможность изменять размер как по высоте, так и по ширине, но его метод изменения размера:

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

не хватает newHeight параметр.

Генерируемое исключение RuntimeException гласит:

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

Как я могу это изменить?

Это было полезно?

Решение

Не анализируя код, чтобы понять, в чем может заключаться проблема, я могу сказать, что если целью является сохранение соотношения сторон изображений, то новый параметр высоты не нужен.Это всегда будет фиксированное соотношение ширины.

Обновить:

Я запустил код против своего собственного тестового образа, и он действительно работает так, как ожидалось.Ошибка, которую вы получаете, скорее всего, вызвана тем, что программа не может найти указанное вами исходное изображение.Я получаю ту же ошибку, когда указываю исходное изображение, которое не существует.

Попробуйте использовать абсолютный путь (включая букву диска и т.д.) Для вашего исходного изображения.

ОБНОВЛЕНИЕ 2

Добавьте следующий код после этой строки..

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");
}

Это сообщит вам, если программе не удается загрузить исходное изображение.

Другие советы

Почему вы применяете смягчение для изменения размера, это должно быть ядро sharpen -1 -2 -1 -2 12+ q2-1 -2 -1, где типичное q может быть 28, и вы не применяете версию drawImage с изменяемым размером

(q = 36 эквивалентно вашему F = 0,05 для резкости)

Судя по трассировке стека, исключение генерируется этой строкой:

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

Я бы подумал, что это, вероятно, потому, что temp.getWidth и temp.getHeight возвращаются значения -1, потому что загрузка изображения еще не завершена.

В Интернете доступны учебные пособия и примеры по работе с изображениями на Java.Один из образцов находится здесь http://snippets.dzone.com/posts/show/92.Ищите код, используя ImageObserver.

Вы должны присвоить программе начальный параметр в диапазоне от 0 до 1.Я сделал это, и это сработало идеально.

адаптируйте это:

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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top