SORU
29 HAZİRAN 2011, ÇARŞAMBA


Java - resim piksel dizisi olsun

BufferedImage piksel veri (int formu int[][]) almak için en hızlı yol arıyorum. Amacım piksel adresi için mümkün 5 ** *resmi 6* kullanarak. Bulduğum tüm yöntemleri bu (çoğu int[]s dönüş) yapmayın.

CEVAP
27 ŞUBAT 2012, PAZARTESİ


Sadece etrafında piksel erişmek için en hızlı yoludur bu aynı konu ile oynuyordum. Ben şu anda bunu yapmak için iki yolu olduğunu biliyorum:

  1. Bufferedİmage kullanarak getRGB() @tskuzzy cevabı açıklanan yöntemi.
  2. Piksel erişerek dizi doğrudan kullanarak

    byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
    

Büyük görüntülerle çalışıyorsanız ve performans sorunu varsa, ilk yöntem kesinlikle gitmek için yol değildir. getRGB() Bu yöntem bir int içine, kırmızı, yeşil ve mavi alfa değerleri birleştirir ve daha sonra çoğu durumda ters bu değerleri geri almak için yapacağım hangi sonucu verir.

İkinci yöntem, kırmızı, yeşil ve mavi değerleri doğrudan her piksel için geri dönecek ve eğer bir alfa kanalı varsa alfa değer katacak. Bu yöntemi kullanarak hesaplama endeksleri açısından daha zor, ama ilk yaklaşımı çok daha hızlı.

Benim uygulama sadece ikinci ilk yaklaşımdan geçerek 90% daha fazla piksel işleme süresini azaltmak için başardı!

Burada Kur iki yaklaşım karşılaştırmak için bir karşılaştırma:

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import javax.imageio.ImageIO;

public class PerformanceTest {

   public static void main(String[] args) throws IOException {

      BufferedImage hugeImage = ImageIO.read(PerformanceTest.class.getResource("12000X12000.jpg"));

      System.out.println("Testing convertTo2DUsingGetRGB:");
      for (int i = 0; i < 10; i  ) {
         long startTime = System.nanoTime();
         int[][] result = convertTo2DUsingGetRGB(hugeImage);
         long endTime = System.nanoTime();
         System.out.println(String.format("%-2d: %s", (i   1), toString(endTime - startTime)));
      }

      System.out.println("");

      System.out.println("Testing convertTo2DWithoutUsingGetRGB:");
      for (int i = 0; i < 10; i  ) {
         long startTime = System.nanoTime();
         int[][] result = convertTo2DWithoutUsingGetRGB(hugeImage);
         long endTime = System.nanoTime();
         System.out.println(String.format("%-2d: %s", (i   1), toString(endTime - startTime)));
      }
   }

   private static int[][] convertTo2DUsingGetRGB(BufferedImage image) {
      int width = image.getWidth();
      int height = image.getHeight();
      int[][] result = new int[height][width];

      for (int row = 0; row < height; row  ) {
         for (int col = 0; col < width; col  ) {
            result[row][col] = image.getRGB(row, col);
         }
      }

      return result;
   }

   private static int[][] convertTo2DWithoutUsingGetRGB(BufferedImage image) {

      final byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
      final int width = image.getWidth();
      final int height = image.getHeight();
      final boolean hasAlphaChannel = image.getAlphaRaster() != null;

      int[][] result = new int[height][width];
      if (hasAlphaChannel) {
         final int pixelLength = 4;
         for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel  = pixelLength) {
            int argb = 0;
            argb  = (((int) pixels[pixel] & 0xff) << 24); // alpha
            argb  = ((int) pixels[pixel   1] & 0xff); // blue
            argb  = (((int) pixels[pixel   2] & 0xff) << 8); // green
            argb  = (((int) pixels[pixel   3] & 0xff) << 16); // red
            result[row][col] = argb;
            col  ;
            if (col == width) {
               col = 0;
               row  ;
            }
         }
      } else {
         final int pixelLength = 3;
         for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel  = pixelLength) {
            int argb = 0;
            argb  = -16777216; // 255 alpha
            argb  = ((int) pixels[pixel] & 0xff); // blue
            argb  = (((int) pixels[pixel   1] & 0xff) << 8); // green
            argb  = (((int) pixels[pixel   2] & 0xff) << 16); // red
            result[row][col] = argb;
            col  ;
            if (col == width) {
               col = 0;
               row  ;
            }
         }
      }

      return result;
   }

   private static String toString(long nanoSecs) {
      int minutes    = (int) (nanoSecs / 60000000000.0);
      int seconds    = (int) (nanoSecs / 1000000000.0)  - (minutes * 60);
      int millisecs  = (int) ( ((nanoSecs / 1000000000.0) - (seconds   minutes * 60)) * 1000);


      if (minutes == 0 && seconds == 0)
         return millisecs   "ms";
      else if (minutes == 0 && millisecs == 0)
         return seconds   "s";
      else if (seconds == 0 && millisecs == 0)
         return minutes   "min";
      else if (minutes == 0)
         return seconds   "s "   millisecs   "ms";
      else if (seconds == 0)
         return minutes   "min "   millisecs   "ms";
      else if (millisecs == 0)
         return minutes   "min "   seconds   "s";

      return minutes   "min "   seconds   "s "   millisecs   "ms";
   }
}

Çıkış tahmin edebilir misiniz? ;)

Testing convertTo2DUsingGetRGB:
1 : 16s 911ms
2 : 16s 730ms
3 : 16s 512ms
4 : 16s 476ms
5 : 16s 503ms
6 : 16s 683ms
7 : 16s 477ms
8 : 16s 373ms
9 : 16s 367ms
10: 16s 446ms

Testing convertTo2DWithoutUsingGetRGB:
1 : 1s 487ms
2 : 1s 940ms
3 : 1s 785ms
4 : 1s 848ms
5 : 1s 624ms
6 : 2s 13ms
7 : 1s 968ms
8 : 1s 864ms
9 : 1s 673ms
10: 2s 86ms

BUILD SUCCESSFUL (total time: 3 minutes 10 seconds)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Learn Math Tutorials

    Learn Math T

    20 Kasım 2011
  • Miles Fisher

    Miles Fisher

    8 NİSAN 2009
  • ShayLoss

    ShayLoss

    5 Kasım 2009