[リストへもどる]
一括表示

投稿時間:2003/02/07(Fri) 07:26
投稿者名:のぶ
URL :
タイトル:
白黒ビットマップ形式でpictureを保存する方法
はじめまして
 SavePictureでPictureBoxのイメージを
以下のようにビットマップ形式で画像を保存できますが、
 この時白黒ビットマップ形式で保存する方法を教えて下さい。

Picture1.AutoRedraw = True
Picture1.Line (0, 0)-(2000, 2000)
SavePicture Picture1.Image, App.Path & "\test.bmp"

 SavePictureで保存するとシステムに依存してしまい、
フルカラーで保存されるということは分かったのですが、
白黒2値で保存したいのです。(サイズを軽くするため)
※ちなみにBackColor/FillColor/ForeColorは白黒に設定しています。

 ここの掲示板でNo1124関連(1128,1124)を見つけたのですが、
APIというものがよく分からないのです。
宜しくお願いします。

投稿時間:2003/02/07(Fri) 10:21
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 白黒ビットマップ形式でpictureを保存する方法
> 白黒2値で保存したいのです。(サイズを軽くするため)
その画像を後どのように使用されるつもりでしょうか?
一度アクセサリ内のペイントを使ってモノクロ保存して見て下さい。
それが使い物になるかどうか?
グレイスケールならまだいいかも知れませんが?

と言う訳でサイズを軽くしたいならJPG形式で保存されたらいかがですか
(JPG形式での保存方法は、ここのグラフィック関係を見て下さい)
参考までに 元の画像Bmp形式(549kb) を
白黒2直BMP形式で保存すると 25kb
JPGで80%圧縮で保存すると    16kb

>  ここの掲示板でNo1124関連(1128,1124)を見つけたのですが、
> APIというものがよく分からないのです。
> 宜しくお願いします。
画像を加工しようと思えばAPIは必須です。それもかなり複雑な!

画像関係に興味があるのでしたら下記のHPを覗いて見て下さい。
お望みのサンプルの他画像処理関係の色んなサンプルがあります。
http://www001.upp.so-net.ne.jp/shige-3peace/index.htm

投稿時間:2003/02/07(Fri) 21:17
投稿者名:のぶ
URL :
タイトル:
Re^2: 白黒ビットマップ形式でpictureを保存する方法
回答ありがとうございます。

> その画像を後どのように使用されるつもりでしょうか?
> 一度アクセサリ内のペイントを使ってモノクロ保存して見て下さい。
> それが使い物になるかどうか?
SendKeys関数でとりあえず作ってみましたが、
「今一歩」、という感じでした。(PCに左右されました。)

> グレイスケールならまだいいかも知れませんが?
>
> と言う訳でサイズを軽くしたいならJPG形式で保存されたらいかがですか
> (JPG形式での保存方法は、ここのグラフィック関係を見て下さい)
出来るだけ画質を劣化したくないので...(生データのままにしたいので)

> 画像を加工しようと思えばAPIは必須です。それもかなり複雑な!
>
> 画像関係に興味があるのでしたら下記のHPを覗いて見て下さい。
> http://www001.upp.so-net.ne.jp/shige-3peace/index.htm
やはりAPIは必須ですか、ここも探していたのですが、
今の私の理解力からは派生treeの方でやってみます。
本当にありがとうございました。

投稿時間:2003/02/07(Fri) 17:20
投稿者名:killer
Eメール:
URL :
タイトル:
Re: 白黒ビットマップ形式でpictureを保存する方法
> はじめまして
>  SavePictureでPictureBoxのイメージを
> 以下のようにビットマップ形式で画像を保存できますが、
>  この時白黒ビットマップ形式で保存する方法を教えて下さい。
>
> Picture1.AutoRedraw = True
> Picture1.Line (0, 0)-(2000, 2000)
> SavePicture Picture1.Image, App.Path & "\test.bmp"
>
>  SavePictureで保存するとシステムに依存してしまい、
> フルカラーで保存されるということは分かったのですが、
> 白黒2値で保存したいのです。(サイズを軽くするため)
> ※ちなみにBackColor/FillColor/ForeColorは白黒に設定しています。
>
>  ここの掲示板でNo1124関連(1128,1124)を見つけたのですが、
> APIというものがよく分からないのです。
> 宜しくお願いします。

 文化オリエント株式会社のLEADTOOLSを使えば簡単にできるけど・・・
 それではダメなのかな?

投稿時間:2003/02/07(Fri) 17:38
投稿者名:k.k
Eメール:gtk2k@hotmail.com
URL :
タイトル:
Re^2: 白黒ビットマップ形式でpictureを保存する方法
LEADTOOLSはちょっと手が出にくい値段ですよね。
API関数に便利な関数がありますのでこの関数を使用すれば
白黒ビットマップとしての画像データを取得できますので、
あとは、ファイルを開いてヘッダーとパレットデータを書き込んあとに、このデータを書き込めば
白黒ビットマップができます。
とまあ、簡単な説明にまとめちゃいましたが結構大変ですね。
デバイスコンテキストや、ビットマップファイルの構造などの知識が必要です。
API関数を使用しなくてもできないこともないですが、花ちゃんがいってるように、結構複雑
になります。
まず、白黒ビットマップは1ピクセルに対して1ビットが割り当てられています。
つまり、ビット事に処理を行わなければなりません。
あと、知っておいてほしいのは、画像データの部分は下のラインから上のラインの順に入っている
ということと、ラインごとのデータは4の倍数バイトでなければならないということ。
つまり4*8=16ピクセルの倍数でないといけないので、足らないところは0で埋めなければなりません。
この処理部部分が結構大変です。

投稿時間:2003/02/07(Fri) 21:56
投稿者名:のぶ
URL :
タイトル:
Re^3: 白黒ビットマップ形式でpictureを保存する方法
killerさん、k.k さん、回答ありがとうございます。

> LEADTOOLSはちょっと手が出にくい値段ですよね。
確かに...けど今後の参考になりました。

> API関数に便利な関数がありますのでこの関数を使用すれば
> 白黒ビットマップとしての画像データを取得できますので、
ちなみに、その関数のサンプルもしくはヒントになるようなページはありますか?

> あとは、ファイルを開いてヘッダーとパレットデータを書き込んあとに、このデータを書き込めば
> 白黒ビットマップができます。
> とまあ、簡単な説明にまとめちゃいましたが結構大変ですね。
> デバイスコンテキストや、ビットマップファイルの構造などの知識が必要です。
カラービットマップの構造体は結構あるんですが、
モノクロとなると見つかりません...(スイマセン私の探し方が悪いのかも知れません。)

> API関数を使用しなくてもできないこともないですが、花ちゃんがいってるように、結構複雑
> になります。
> まず、白黒ビットマップは1ピクセルに対して1ビットが割り当てられています。
はい、ON/OFFが1ビットですよね?
> つまり、ビット事に処理を行わなければなりません。
> あと、知っておいてほしいのは、画像データの部分は下のラインから上のラインの順に入っている
> ということと、ラインごとのデータは4の倍数バイトでなければならないということ。
はい判りました。???ホントかな?
1000
0001
0001
0001
という4ラインのデータなら
0001
0001
0001
1000
に直すと言うことでしょうか?

> つまり4*8=16ピクセルの倍数でないといけないので、足らないところは0で埋めなければなりません。
> この処理部部分が結構大変です。
なんとなく、これはラインごとに0で埋めるのでしょうか?
ちょと、頑張って探してみます。

投稿時間:2003/02/07(Fri) 22:31
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^4: 白黒ビットマップ形式でpictureを保存する方法
> > 白黒ビットマップとしての画像データを取得できますので、
> ちなみに、その関数のサンプルもしくはヒントになるようなページはありますか?

先ほどの回答に書いたつもりですが! ご覧になられなかったのでしょうか?
http://www001.upp.so-net.ne.jp/shige-3peace/index.htm
の VB Freaks の中に 画像の2直化変換 他のサンプルがありますよ

投稿時間:2003/02/11(Tue) 10:19
投稿者名:k.k
Eメール:
URL :
タイトル:
Re^4: 白黒ビットマップ形式でpictureを保存する方法
> カラービットマップの構造体は結構あるんですが、
> モノクロとなると見つかりません...(スイマセン私の探し方が悪いのかも知れません。)
カラーもモノクロも一緒ですよ。
パレットの数が違うだけ(ビット数もだけど)

> 1000
> 0001
> 0001
> 0001
> という4ラインのデータなら
> 0001
> 0001
> 0001
> 1000
> に直すと言うことでしょうか?
うん、こういうこと

> > つまり4*8=16ピクセルの倍数でないといけないので、足らないところは0で埋めなければなりません。
> > この処理部部分が結構大変です。
> なんとなく、これはラインごとに0で埋めるのでしょうか?
> ちょと、頑張って探してみます。
APIではこの辺の計算などはやってくれるので、こんな難しいことを考えずにすみます。

で、とりあえずサンプルを書いてみました。
ピクチャーボックスとコマンドボタンをひとつずつおいて、
ピクチャーボックスのAutoRedrawをTrueにScaleModeをピクセルにしてください。
GetDibits関数を使って白黒ビットマップを取得します。
つまり、BITMAPINFOHEADER構造体のbiBitcountメンバでビット数を1にし、
BITMAPINFO構造体でbmiColorsメンバをbmiColors(1)(要素数が2つ)
にすればモノクロビットマップを取得することができます。
GetDibits関数を使用すれば、256色ビットマップ、16ビットカラービットマップ
などのビットマップにも変換することができます。
Private Type BITMAPFILEHEADER
        bfType As Integer
        bfSize As Long
        bfReserved1 As Integer
        bfReserved2 As Integer
        bfOffBits As Long
End Type

Private Type BITMAPINFOHEADER
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type
Private Type RGBQUAD
        rgbBlue As Byte
        rgbGreen As Byte
        rgbRed As Byte
        rgbReserved As Byte
End Type

Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors(1) As RGBQUAD  '白黒ビットマップとして取得するため配列を2つにする
End Type

Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Const DIB_RGB_COLORS = 0 '  color table in RGBs

Private Sub Command1_Click()
Dim rc As Long
Dim BmpInfo As BITMAPINFO
Dim PicData() As Byte
Dim BmpFileHeader As BITMAPFILEHEADER

With BmpInfo.bmiHeader
    .biSize = 40
    .biWidth = Picture1.ScaleWidth
    .biHeight = Picture1.ScaleHeight
    .biPlanes = 1
    .biBitCount = 1 'ここでビット数(色数)を設定する。白黒なのでここでは1を設定。
End With

'まず、5番目の引数(lpBits)に0を設定して、GetDiBitsを実行するとバッファに必要なバイト数が戻ってくる
rc = GetDIBits(Picture1.hdc, Picture1.Picture, 0, Picture1.ScaleHeight - 1, ByVal 0&, BmpInfo, DIB_RGB_COLORS)
'バッファを確保する
ReDim PicData(BmpInfo.bmiHeader.biSizeImage - 1)
'再度改めて、5番目に確保したバッファを設定して、GetDibitsを実行して白黒ビットマップのデータを取得
rc = GetDIBits(Picture1.hdc, Picture1.Picture, 0, Picture1.ScaleHeight, PicData(0), BmpInfo, DIB_RGB_COLORS)

'パレットを設定
'黒 (すべて0なので省略してもかまわない)
With BmpInfo.bmiColors(0)
    .rgbBlue = 0
    .rgbGreen = 0
    .rgbRed = 0
    .rgbReserved = 0
End With
'白
With BmpInfo.bmiColors(1)
    .rgbBlue = &HFF
    .rgbGreen = &HFF
    .rgbRed = &HFF
    .rgbReserved = 0
End With

'確認のため描画する
rc = SetDIBits(Picture1.hdc, Picture1.Picture, 0, Picture1.ScaleHeight, PicData(0), BmpInfo, DIB_RGB_COLORS)
'リフレッシュして表示する
Picture1.Refresh

'ファイルヘッダーを設定
With BmpFileHeader
    .bfType = &H4D42 '"BM"
    .bfSize = Len(BmpFileHeader) + Len(BmpInfo) + BmpInfo.bmiHeader.biSizeImage
    .bfOffBits = Len(BmpFileHeader) + Len(BmpInfo)
End With
'ファイルを開く(新規作成)
Open "c:\mono.bmp" For Binary As #1
'ファイルヘッダーを書き込む
Put #1, , BmpFileHeader
'ヘッダーを書き込み
Put #1, , BmpInfo
'画像データを書き込む
Put #1, , PicData
Close #1
End Sub

でも、この減色ほうほうだと、簡単なアルゴリズムを使用しているため、あまりきれいではありません。

投稿時間:2003/02/18(Tue) 23:06
投稿者名:のぶ
Eメール:
URL :
タイトル:
Re^お礼申し上げます。5: 白黒ビットマップ形式でpictureを保存する方法
花ちゃん さん
k.k さん
お礼が遅くなって申し訳ありませんでした。m(_ _)m
大変参考になりました。
ありがとうございます。
以後、ドン亀ながら1つ1つ
VBマスターすることを目指して頑張ります。