سؤال

أنا حاليا تحول مجموعة من القيم بكسل (أنشئت أصلا مع جافا.awt.صورة.PixelGrabber كائن) في صورة كائن باستخدام التعليمات البرمجية التالية:

public Image getImageFromArray(int[] pixels, int width, int height) {
    MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width);
    Toolkit tk = Toolkit.getDefaultToolkit();
    return tk.createImage(mis);
}

هل من الممكن تحقيق نفس النتيجة باستخدام فئات من ImageIO حزمة(ق) حتى لا تضطر إلى استخدام AWT أدوات?

مجموعة الأدوات.getDefaultToolkit() لا يبدو أن تكون 100 ٪ موثوق بها و في بعض الأحيان يرمون AWTError ، بينما ImageIO الطبقات يجب أن تكون متاحة دائما ، وهذا هو السبب أنا مهتم بتغيير الأسلوب.

هل كانت مفيدة؟

المحلول

يمكنك إنشاء صورة بدون استخدام ImageIO.مجرد إنشاء BufferedImage باستخدام نوع الصورة مطابقة محتويات مجموعة بكسل.

public static Image getImageFromArray(int[] pixels, int width, int height) {
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            WritableRaster raster = (WritableRaster) image.getData();
            raster.setPixels(0,0,width,height,pixels);
            return image;
        }

عند العمل مع PixelGrabber, لا تنسى أن استخراج RGBA معلومات من مجموعة بكسل قبل الاتصال getImageFromArray.هناك مثال على هذا في handlepixelmethod في PixelGrabber جافادوك.مرة كنت تفعل ذلك ، تأكد من نوع الصورة في BufferedImage منشئ BufferedImage.TYPE_INT_ARGB.

نصائح أخرى

باستخدام النقطية لدي ArrayIndexOutOfBoundsException حتى عندما خلق BufferedImage مع TYPE_INT_ARGB.ومع ذلك, باستخدام setRGB(...) طريقة BufferedImage عملت بالنسبة لي.

جافادوك على BufferedImage.getData() يقول:"النقطية التي هي نسخ من بيانات الصورة."

هذا الكود يعمل بالنسبة لي ولكن أنا أشك في ذلك كفاءة:

        // Получаем картинку из массива.
        int[] pixels = new int[width*height];
            // Рисуем диагональ.
            for (int j = 0; j < height; j++) {
                for (int i = 0; i < width; i++) {
                    if (i == j) {
                        pixels[j*width + i] = Color.RED.getRGB();
                    }
                    else {
                        pixels[j*width + i] = Color.BLUE.getRGB();
                        //pixels[j*width + i] = 0x00000000;
                    }
                }
            }

BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
    pixelImage.setRGB(0, 0, width, height, pixels, 0, width);

لقد كان نجاح جيدة باستخدام جافا.awt.الروبوت إلى الاستيلاء على لقطة من الشاشة (أو جزء من الشاشة) ، ولكن للعمل مع ImageIO, سوف تحتاج إلى تخزينها في BufferedImage بدلا من الذاكرة صورة المصدر.ثم يمكنك استدعاء واحد ثابت طريقة ImageIO وحفظ الملف.محاولة شيء من هذا القبيل:

// Capture whole screen
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capturedImage = new Robot().createScreenCapture(region);

// Save as PNG
File imageFile = new File("capturedImage.png");
ImageIO.write(capturedImage, "png", imageFile);

هذا هو واحد من أعلى صوت مسألة ذات الكلمات الدلالية مع ImageIO على ذلك ، أعتقد أنه لا يزال هناك مجالا أفضل حل, حتى لو كان السؤال القديم.:-)

إلقاء نظرة على BufferedImageFactory.java فئة من المصدر المفتوح imageio المشروع على GitHub.

مع ذلك, يمكنك ببساطة كتابة:

BufferedImage image = new BufferedImageFactory(image).getBufferedImage();

آخر الشيء الجيد هو أن هذا النهج باعتباره أسوأ الأحوال ، حول نفس الأداء (الوقت) كما PixelGrabberعلى أساس الأمثلة في هذا الموضوع.في معظم الحالات الشائعة (عادة JPEG) ، عن أسرع مرتين.في أي حال ، فإنه يستخدم ذاكرة أقل.

إلى جانب مكافأة, لون نموذج تخطيط بكسل من الصورة الأصلية يتم الاحتفاظ بها بدلا من ترجمتها إلى الباحث ARGB مع نموذج اللون الافتراضي.هذا قد حفظ ذاكرة إضافية.

(PS:المصنع أيضا يدعم والاختزال, منطقة من الفائدة والتقدم المستمعين إذا كان أي شخص مهتم.:-)

كان عندي نفس المشكلة من الجميع محاولة تطبيق الإجابة الصحيحة لهذا السؤال ، الباحث مجموعة في الواقع الحصول على OutOfboundException حيث أنها ثابتة إضافة واحد أكثر من مؤشر بسبب طول المصفوفة يجب أن يكون عرضا*الارتفاع*3 بعد هذا لم أستطع الحصول على صورة لذلك أنا ثابت أنه وضع النقطية للصورة

public static Image getImageFromArray(int[] pixels, int width, int height) {
        BufferedImage image = new BufferedImage(width, height,     BufferedImage.TYPE_INT_ARGB);
        WritableRaster raster = (WritableRaster) image.getData();
        raster.setPixels(0,0,width,height,pixels);
        image.setData(raster); 
        return image;
    }

ويمكنك أن ترى الصورة إذا ش تظهر على الملصق على jframe مثل هذا

    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(new FlowLayout());
    frame.getContentPane().add(new JLabel(new ImageIcon(image)));
    frame.pack();
    frame.setVisible(true);

وضع الصورة على imageIcon().آخر نصيحة يمكنك محاولة تغيير Bufferedimage.TYPE_INT_ARGB إلى شيء آخر يطابق الصورة التي حصلت على مجموعة من هذا النوع مهم جدا لدي مجموعة من 0 و -1 إذا كنت تستخدم هذا النوع BufferedImage.TYPE_3BYTE_BGR

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top