2016-09-09 50 views
0

24ビットBMPイメージ(ImageIOまたは外部ライブラリなし)を読み込み、8ビットグレースケールのBMPイメージにするプログラムを作成する必要があります。イメージのヘッダーを8ビットにするには、Source 1Source 2に変更する必要があります。だから、私はその後、私が手に私のファイルを読み込み、このBMPイメージを8ビットのグレースケールに変換する方法

FileInputStream image= new FileInputStream(path); 
byte[] bytesImage = new byte[image.available()]; 
image.read(bytesImage); 
image.close(); 

のようなバイトベクトルを生成まず

... BITCOUNTバイトが29とヘッダの30であり、それらを変更しようという hereを読みます画像ヘッダとその後、私は、ヘッダー情報がこのような8ビットBMP作るためにバイトを変更するには、新しいベクトルに

int width = byteToInt(bytesImage[18], bytesImage[19], bytesImage[20], bytesImage[21]); 
int height = byteToInt(bytesImage[22], bytesImage[23], bytesImage[24], bytesImage[25]); 
int header = byteToInt(bytesImage[14], bytesImage[15], bytesImage[16], bytesImage[17]) + 14; // Add 14 for the header 
vecGrey = Arrays.copyOf(bytesImage, bytesImage.length); 

をコピーします

byte[] values = intToByte(8); 
vecGrey[28] = values[0]; // This is the index for the BitCount byte 1 
vecGrey[29] = values[1]; // and this one is the index for the second one. 

オーケーは今、私はここにショーとしてdiferentヘッダでvecGreyを書くしようとした場合、私はvecGreyでヘッダを持つファイルを書き込むことはできませんいくつかの理由で、問題が来る:

FileOutputStream aGrey = new FileOutputStream(name+ "-gray.bmp"); 
aGrey.write(vecGrey); 
aGrey.close(); 
// This is a method that displays the resulting image in a frame... 
makeInterface(name + "-gray.bmp"); 

私は私がしなければならないことを知っていますvecGreyの値を変更しますが、これは不正な出力(おそらくグレースケールの画像ではないか、まったく画像ではない)を表示するように働くはずです。私はmakeInterface()メソッドで生成したファイルを読み込むしようとすると、しかし、私はだから私は、プログラムがあることをasume画像ヘッダ

を読み取ることができませんでし

javax.imageio.iioexceptionを取得しますヘッダーを正しく読み取れませんが、理由はわかりません。私がBitCountの値を16に変更しても、それは動作しますが、1,4、または8には同じエラーでは動作しません。私はホールコードをスペイン語でアップロードしませんでしたが、必要ならば翻訳できますそれを編集してください。

ありがとうございます!

EDIT1:私は640x480の24ビットBMPイメージのみを使用しているので、パディングをチェックする必要はありません。

+0

BMPはそれほど単純ではありませんが、行の長さは4になりました(現在は1バイトになります)。フォーマット参照を使用して、ボックスのような独自の小さなグレースケール画像を作成してみてください。そして変換を行います。 –

+0

@JoopEggen申し訳ありません!私は640x480のBMP 24ビットイメージしか使用していないことを忘れていたので、パディングについて心配する必要はありません。私はこれら2つのフォーマットの参考文献[ここ](http://www.daubnet.com/en/file-format-bmp)と[ここ](https://upload.wikimedia.org/wikipedia/commons/c)を使用しています。 /c4/BMPfileFormat.png)。 –

+0

コーディングの楽しみを楽しませることを怠っていません。グレースケール画像を作成し、データを分析することを検討してください。あなたが注文ByteOrder.LITTLE_ENDIANを使ってByteBufferを使わなかったのは残念ですが、getShort、getInt、earier –

答えて

2

BMPを24ビットから8ビットに変更するときは、ヘッダーのいくつかの変更が必要です。まず、画像のサイズが変更されます(バイト3〜6)。従って新しいサイズが

headerSize {通常54} +(numberOfColors * 4)となるべきピクセル当たり1バイト +幅{これは、カラーテーブル/パレットのためであり、Iは256でこれを設定するお勧めします} *高さ{実際のピクセル数}

次に、右のカラーテーブル/パレット後、この値は、バイト11-14に位置していると、新しい値があるべき画素データ用ら:

headerSize + numberOfColors * 4

次に必要にバイト15から始まるBITMAPINFOHEADERを変更します。バイト15〜18は、この第2ヘッダーのサイズ(通常は40)を含む必要があります。グレースケールに変換したい場合は無視し、バイト29と30に達するまで変更しないでくださいあなたが既に計算した新しい画像サイズを入力しなければならないことがわかっている限り、35〜38バイトのbitCountを変更します。バイト47〜50はカラーパレットの色数を決定します。あなたはグレースケールをやっています。私は256色を使うことをお勧めします。なぜ私は少し説明します。バイト51-54は重要な色の数を含み、すべての色が重要であることを示すために0に設定される。

次は、ヘッドテーブルのすぐ隣にカラーテーブル/パレットを追加する必要があります。私が256色をお勧めする理由は、カラーパレットが次のように書かれているからです:[B、G、R、0]ここで、BGRはRGB形式の青、緑、赤の色値と最後に定数0、 R = G = BのRGB値を書き込むパレットを作成して、灰色の陰影を生成することができます。したがって、ヘッダーの隣に、この新しい一連のバイトを昇順で追加する必要があります。

[0,0,0,0] [1,1,0,0] [2,2,2,0] [3,3,3,0] ... [255,255,255,0]

カラーパレットの「エントリ」の数であるため、イメージの新しいサイズを計算する必要があるnumberOfColorsは256であることに注意してください。

次に、テーブル/パレットの後に新しいピクセルデータを書きたいと思うでしょう。 24ビットのイメージが与えられているので、ピクセルマトリックスを抽出して各ピクセルのRGB値を取得できます。値が-128から127までのバイト配列を持っていることを忘れないでください。 int値ですので、任意のチャンネルの強度が<であれば、それに256を加えてint値を得ると、灰色の輝度を与える方程式を適用することができます:

Y '= 0.299R' + 0.587G '+ 0.114B' ここで、Y'はグレーの強度、RGBは赤、緑および青の強度である。

式の結果を丸めて、imangeにバイトとして書き込んで、元のイメージのすべてのピクセルで同じように処理できます。

完了したら、ファイルの最後に2つの予約済みの0を追加するだけで、新しい8ビットグレースケールの24ビットイメージのイメージを作成する必要があります。

これが役に立った。

源:あなたが提供される一つと: https://en.wikipedia.org/wiki/BMP_file_format https://en.wikipedia.org/wiki/Grayscale

0

あなたが最初の24ビットのBMPと同様に、グレースケールBMPの両方のHEXフォーマットを参照してくださいする必要があり、その後、あなたは賢明なステップに行く必要があり、 -read 24ビットbmpヘッダー - オフセット後のデータの読み取り。 - 8ビットグレースケール画像のヘッダを書き込む - 8ビットグレースケール画像に書き込む。 注:rgbビットを8ビットのグレースケールに変換し、rgbビットを3で割る必要があります。

関連する問題