سؤال

أرسل لي مدرسي هذا الرمز، الذي من المفترض أن يكون جزءا لا يتجزأ من مشروع مستمر. الشيء هو أنه لا يعمل.

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

سيخبرك هذا إذا فشل البرنامج في تحميل الصورة المصدر.

نصائح أخرى

لماذا تطبق تليين لتغيير حجمها يجب أن تكون شحذ kernal -1 -2 -2 12 + q -2 -1 -2 -1 حيث يمكن أن يكون Q Tipical 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