2014-10-27 82 views
1

有一個任務從int RGB矩陣生成BMP文件,並從BMP圖像讀取該矩陣。java從像素矩陣和反向創建BMP圖像

我用這個類來生成BMP文件,但它似乎是難以逆轉這種方法來獲取從圖像rgbValues陣列:

/** 
* Class for creating bmp images from the pixel matrix (an int matrix). 
* @author eafkuor 
* @link http://forum.codecall.net/topic/62457-creating-a-bmp-image-in-java/ 
*/ 
import java.io.File; 
import java.io.FileOutputStream; 

public class BMP { 
    private final static int BMP_CODE = 19778; 

    byte[] bytes; 

    public void saveBMP(String filename, int[][] rgbValues) { 
     try { 
      FileOutputStream fos = new FileOutputStream(new File(filename)); 

      bytes = new byte[54 + 3 * rgbValues.length * rgbValues[0].length + getPadding(rgbValues[0].length) * rgbValues.length]; 

      saveFileHeader(); 
      saveInfoHeader(rgbValues.length, rgbValues[0].length); 
      saveRgbQuad(); 
      saveBitmapData(rgbValues); 

      fos.write(bytes); 

      fos.close(); 

     } catch (Exception ignored) {} 

    } 

    private void saveFileHeader() { 
     byte[] a = intToByteCouple(BMP_CODE); 
     bytes[0] = a[1]; 
     bytes[1] = a[0]; 

     a = intToFourBytes(bytes.length); 
     bytes[5] = a[0]; 
     bytes[4] = a[1]; 
     bytes[3] = a[2]; 
     bytes[2] = a[3]; 

     //data offset 
     bytes[10] = 54; 
    } 

    private void saveInfoHeader(int height, int width) { 
     bytes[14] = 40; 

     byte[] a = intToFourBytes(width); 
     bytes[22] = a[3]; 
     bytes[23] = a[2]; 
     bytes[24] = a[1]; 
     bytes[25] = a[0]; 

     a = intToFourBytes(height); 
     bytes[18] = a[3]; 
     bytes[19] = a[2]; 
     bytes[20] = a[1]; 
     bytes[21] = a[0]; 

     bytes[26] = 1; 

     bytes[28] = 24; 
    } 

    private void saveRgbQuad() { 

    } 

    private void saveBitmapData(int[][] rgbValues) { 
     int i; 

     for (i = 0; i < rgbValues.length; i++) { 
      writeLine(i, rgbValues); 
     } 

    } 

    private void writeLine(int row, int[][] rgbValues) { 
     final int offset = 54; 
     final int rowLength = rgbValues[row].length; 
     final int padding = getPadding(rgbValues[0].length); 
     int i; 

     for (i = 0; i < rowLength; i++) { 
      int rgb = rgbValues[row][i]; 
      int temp = offset + 3 * (i + rowLength * row) + row * padding; 

      bytes[temp] = (byte) (rgb >> 16); 
      bytes[temp + 1] = (byte) (rgb >> 8); 
      bytes[temp + 2] = (byte) rgb; 
     } 
     i--; 
     int temp = offset + 3 * (i + rowLength * row) + row * padding + 3; 

     for (int j = 0; j < padding; j++) 
      bytes[temp + j] = 0; 

    } 

    private byte[] intToByteCouple(int x) { 
     byte[] array = new byte[2]; 

     array[1] = (byte) x; 
     array[0] = (byte) (x >> 8); 

     return array; 
    } 

    private byte[] intToFourBytes(int x) { 
     byte[] array = new byte[4]; 

     array[3] = (byte) x; 
     array[2] = (byte) (x >> 8); 
     array[1] = (byte) (x >> 16); 
     array[0] = (byte) (x >> 24); 

     return array; 
    } 

    private int getPadding(int rowLength) { 

     int padding = (3 * rowLength) % 4; 
     if (padding != 0) 
      padding = 4 - padding; 


     return padding; 
    } 
} 

是否有做這樣的事情在任何Java的lib?或者,也許有人可以建議如何反轉BMP文件?

+0

javax.imageio.ImageIO應該爲您處理。 – BarrySW19 2014-10-27 20:13:28

+0

@ BarrySW19它不提供BMP處理 – ovnia 2014-10-27 20:33:11

+0

它應該 - 在我的系統上「System.out.println(Arrays.toString(ImageIO.getReaderFormatNames()));」 [JPG,BMP,BMP,BMP,BMP,PNG,JPEG,PNG,JPEG,PNG, ,WBMP,GIF,gif]「。你的禮物是什麼?實現者位於所有標準Oracle JDK應具有的com.sun.imageio.plugins.bmp包中。 – BarrySW19 2014-10-28 09:34:59

回答

1

在我看來,使用API​​是一項懶惰的事情,如果任務易於實現,並且您可以更好地理解幕後發生的事情。在你完成至少一次自己的工作之後,你可以使用良心良好的API。最後你SHOULD使用API​​,因爲工作代碼可能比你自己的版本更強大和安全。

翻轉圖像至少在理論上是一件非常簡單的事情。該過程包括兩個步驟:

  1. 把圖像的顏色矩陣到存儲器
  2. 創建一個新的圖像,使得每個像素,從左邊開始,從在存儲器中的圖像選擇時,只有從開始正確的。

爲了說明:

假設我們有一個圖像是在寬度和4像素的高度4像素。 0表示像素爲黑色,1表示爲白色。

所以我們在實踐中有一個4x4的二進制矩陣。讓我們組成,如下所示:

[1][0] 
[1][0] 

爲了扭轉這種局面,我們只需將陣列複製到一個新的4x4矩陣,但我們的值複製到新的矩陣從右側開始:

[1][0] => [0][1] 
[1][0] => [0][1] 

現在我們有反轉圖像:

[0][1] 
[0][1] 

這是這個想法。

在RGB情況下,原始圖像的矩陣會是這個樣子:

[rgb(255, 255, 255)][rgb(0, 0, 0)] 
[rgb(255, 255, 255)][rgb(0, 0, 0)] 

現在去找出如何提取每個像素的顏色,並將其寫入到一個新的。這是一件容易的事。

+0

我想懶惰的方式)因爲它不是一項主要任務。實際上,正如你所描述的那樣,一切都不容易:有文件中應該實現的bmp格式的標題和一些其他特性 – ovnia 2014-10-27 20:32:13