簡體   English   中英

Java從像素矩陣創建BMP圖像並反轉

[英]java create BMP image from pixel matrix and reverse

有一項任務是從int RGB矩陣生成BMP文件,然后從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庫? 也許有人可以建議如何反轉BMP文件?

我認為,使用API​​是一件容易的事,如果該任務易於實現並且您可以更好地了解幕后情況。 至少自己完成一次之后,您可以使用具有良心的API。 最后,您應該使用API​​,因為工作代碼可能比您自己的版本強大且安全。

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

  1. 將圖像的顏色矩陣放入內存
  2. 創建一個新圖像,以便從內存中的圖像中選擇從左側開始的每個像素,而僅從右側開始。

為了顯示:

假設我們有一個寬度為4px,高度為4px的圖像。 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)]

現在,了解如何提取每個像素的顏色並將其寫入新的顏色。 這是一個容易的任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM