2008-09-24 2 views
24

Я в настоящее время поворота массив значений пикселов (первоначально созданных с объектом java.awt.image.PixelGrabber) в объект изображения, используя следующий код:Включить массив пикселей в объект изображения с помощью ImageIO от Java?

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 Toolkit?

Toolkit.getDefaultToolkit(), кажется, не на 100% надежный и иногда может вызывать AWTError, тогда как классы ImageIO всегда должны быть доступны, поэтому меня интересует изменение моего метода.

ответ

23

Вы можете создать изображение, не используя 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 в javadoc PixelGrabber. Как только вы это сделаете, убедитесь, что тип изображения в конструкторе BufferedImage равен BufferedImage.TYPE_INT_ARGB.

+1

Спасибо bcash, но я получаю java.lang.ArrayIndexOutOfBoundsException при попытке этого кода. Есть идеи? – 2008-09-24 02:53:40

+0

Я думаю, что это близко, нам может понадобиться более подробная информация от Криса с подробностями? похоже, что это должно сработать ... Каковы ваши цели? они RGB? ARGB? какой-то упакованный формат? – 2008-09-24 04:37:39

+0

Пикселы исходят от PixelGrabber как такового: int [] pixels = new int [width * height]; PixelGrabber pg = new PixelGrabber (img, 0, 0, ширина, высота, пиксели, 0, ширина); pg.grabPixels(); – 2008-09-24 05:17:13

1

У меня был хороший успех, используя java.awt.Robot, чтобы захватить снимок экрана (или сегмент экрана), но для работы с 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); 
7

Использование растра Я получил ArrayIndexOutOfBoundsException, даже когда я создал BufferedImage с TYPE_INT_ARGB. Однако для меня работал метод setRGB(...)BufferedImage.

3

JavaDoc on 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); 
0

Поскольку это один из самых высоких голосовала вопрос помеченным ImageIO на SO, я думаю, что есть еще место для лучшего решения, даже если вопрос старый. :-)

Посмотрите на класс BufferedImageFactory.java из моего проекта с открытым исходным кодом imageio в GitHub.

С его помощью вы можете просто написать:

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

Другая хорошая вещь в том, что этот подход, в худшем случае, имеет примерно такую ​​же производительность (время) в качестве PixelGrabber -На примеры уже в этом нить. Для большинства распространенных случаев (обычно JPEG) это примерно в два раза быстрее. В любом случае он использует меньше памяти.

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

(PS: Завод также поддерживает подвыборку, область интересов и прогресс слушателей, если кому-то это интересно.:-)

0

У меня была та же проблема, что и все остальные, пытающиеся применить правильный ответ на этот вопрос, мой массив int фактически получает исключение OutOfboundException, где я исправил его, добавив еще один индекс, потому что длина массива должна быть widht * высота * 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); 

установка изображения на изображениеIcon(). Последний совет, который вы можете попробовать изменить Bufferedimage.TYPE_INT_ARGB на что-то еще, что соответствует изображению, полученному вами от этого типа, очень важно. У меня был массив из 0 и -1, поэтому я использовал этот тип BufferedImage.TYPE_3BYTE_BGR