C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

8ビット画像のトリミング

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■93137 / inTopicNo.1)  8ビット画像のトリミング
  
□投稿者/ エール (1回)-(2019/11/23(Sat) 11:21:51)

分類:[.NET 全般] 

VB.NETを使っています。

8ビット画像を取り込んで、
8ビット画像のままでトリミングして出力したいのですが、

https://dobon.net/vb/dotnet/graphics/triming.html

このページに書かれた方法を使うと

Dim g As Graphics = Graphics.FromImage(canvas)

のところで
追加情報:インデックス付きのピクセル形式をもつイメージからグラフィックス オブジェクトを作成することはできません。

というエラーが発生します。

一度、24bitか32bitする必要があるようです。

8bitのままでクロップしたいのですが
どのようにすれば良いでしょうか?

引用返信 編集キー/
■93138 / inTopicNo.2)  Re[1]: 8ビット画像のトリミング
□投稿者/ Hongliang (921回)-(2019/11/23(Sat) 12:23:24)
System.Drawingの範囲だと、BitmapDataを使って一行ずつコピーすることになりますね。
手順としては、
1. クリップ後の8bppビットマップを格納できるオブジェクトをNew Bitmap(width, height, PixelFormat)で作成する
2. クリップ元、クリップ先のBitmapそれぞれでLockBitsを呼び出してBitmapDataオブジェクトを取得する
3. クリップ元のBitmapData::Scan0から、クリップ先のBitmapData::Scan0に必要な分をコピー
4. Bitmap::UnlockBitsでそれぞれBitmapDataを解放

コピーについてですが。
BitmapData::Scan0はIntPtr型なので、Marshal.Copyメソッドを使って、Byte配列を介してコピーするのがいいでしょう。
クリップ元のsrcX,srcYからclipWidth,clipHeightをクリップ先にコピーするとして、
0 から clipHeight - 1 までの y それぞれについて、
クリップ元先頭アドレス:BitmapData::Scan0 + (y + srcY) * BitmapData::Stride + srcX
クリップ先先頭アドレス:BitmapData::Scan0 + y * BitmapData::Stride
を、clipWidthのサイズのByte配列を使って、For文などで順次Marshal.Copy(1行につき、クリップ元からByte配列へ、Byte配列からクリップ先へと2回)していきます。
引用返信 編集キー/
■93139 / inTopicNo.3)  Re[2]: 8ビット画像のトリミング
□投稿者/ エール (3回)-(2019/11/23(Sat) 13:00:32)
やはり、バイト配列を介す方法しかないのでしょうか?
結構面倒なのですが・・・

引用返信 編集キー/
■93140 / inTopicNo.4)  Re[3]: 8ビット画像のトリミング
□投稿者/ Hongliang (922回)-(2019/11/23(Sat) 13:28:43)
System.Drawingにこだわらないのであれば、WindowsBase.dllおよびPresentationCore.dllを参照して、
System.Windows.Media.Imaging.CroppedBitmapを使うこともできます。
// クリップ前後の処理(画面に表示するだとか)も含めると簡単かどうかは何とも言えませんが。
引用返信 編集キー/
■93141 / inTopicNo.5)  Re[4]: 8ビット画像のトリミング
□投稿者/ エール (4回)-(2019/11/23(Sat) 13:59:42)
なるほどなるほど、
どうもありがとうございました。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ