3

Windows BMP 形式の画像を表すバイト配列があり、ピクセル データをコピーせずBufferedImageに、ライブラリがそれを Java アプリケーションに として表示するようにしたいと考えています。

主な問題は、JDK の のすべての実装がRasterイメージ ピクセルを上から下、左から右の順序で格納するのに対し、BMP ピクセル データは下から上、左から右の順序で格納されることです。これが補正されない場合、結果の画像は垂直方向に反転します。

最も明白な「解決策」は、SampleModelscanlineStrideプロパティを負の値に設定し、バンド オフセット (またはDataBufferの配列オフセット) を左上のピクセル、つまり配列の最後の行の最初のピクセルを指すように変更することです。 . SampleModel残念ながら、負のscanlineStride引数を指定するとすべてのコンストラクターが例外をスローするため、これは機能しません。

現在、リフレクションを使用してフィールドを負の値に強制することで回避していscanlineStrideますが、可能であれば、よりクリーンで移植性の高い方法で実行したいと考えています。たとえば、カプセル化を壊さずに、ピクセルをボトムアップの順序で配置するRasterまたはをだます別の方法はありますか? または、ピクセル行を逆順に表示するandSampleModelをラップするライブラリがどこかにありますか?RasterSampleModel

次のアプローチは避けたいと思います。

  • 画像全体をコピーする (パフォーマンス上の理由から。コードは 1 秒間に何百もの大きな (>= 1M ピクセル) 画像を処理する必要があり、アプリケーションは画像全体を利用できる必要がありますが、通常は小さな (しかし予測が難しい) 画像のみにアクセスします) ) 画像の一部です。)
  • を変更しDataBufferて座標変換を実行します (これは実際には機能しますが、バッファーはスキャンライン/ピクセル レイアウトについて知る必要がないため、別の「汚い」ソリューションです)。
  • Rasterおよび/またはインターフェースを最初から再実装するSampleModel(互換性チェックが (少なくとも Sun JDK で) 実装されているため、特定のサブクラスが必要なSampleModelため、一般的なBottomUpSampleModelラッパー クラスは機能しません。)
4

3 に答える 3

1

という名前の新しいクラスを 1 つだけ使用して、これを実装できることがわかりましBottomUpComponentSampleModelた。スーパークラスコンストラクターを呼び出した後、フィールドの値を拡張ComponentSampleModelして否定しますscanlineStride(幸いなことに、これはではありませprotectedん)。privateすべてのピクセル アドレス計算は正常に機能しますが、 の検証はRaster.createWritableRaster機能しません (小さすぎる配列を指定すると、検出に失敗する可能性があります)。ただし、これは深刻な問題ではありません。

MultiPixelPackedSampleModelorSinglePixelPackedSampleModelでは負の値を受け入れるので、これは必要ありませんscanlineStride。バンド オフセットはありませんが、 にオフセットを設定することで回避できますDataBuffer

于 2010-03-26T11:24:29.917 に答える
0

さらに良いことに、アプリケーションが実際に画像を表示する必要がないように聞こえますか?そもそも画面上で正しく見えるように、そもそも裏返したいと思うのはなぜですか?お持ちのバージョンで動作するロジックを書くだけですか?そのようにBufferedImageを用意する必要はなく、配列を直接操作します。

于 2010-03-17T10:35:46.753 に答える
0

アプリケーション (またはアクセス レイヤー) に、画像の小さな (しかし予測が難しい) 部分にアクセスするときに、そのコピーの変換と反転作業を行わせるのはどうですか?

于 2010-03-17T10:07:00.163 に答える