• ベストアンサー

VB.NETのことで困っています。

VB.NETのプログラムで白黒判別プログラムを作成することになったのですが、GetPicxelの使い方が間違っているらしく正しくカウントしてくれません。 ちなみに今作成している問題のプログラムは以下のプログラムです。 Function CountNumColor(ByRef DotWW As Long, ByRef DotHH As Long, ByRef CHECK_C As Long) As Integer Dim Form1 As Object Dim NumEQ As Double Dim NumNot As Long Dim x, y As Long NumEQ = 0 NumNot = 0 System.Windows.Forms.Application.DoEvents() For x = 0 To DotHH - 1 For y = 0 To DotWW - 1 System.Windows.Forms.Application.DoEvents() If CHECK_C = Val("Bitmap.GetPixel(x,y)") Then NumEQ = NumEQ + 1 Else NumNot = NumNot + 1 Debug.Write("x,y,Val(Bitmap.GetPixel(x, y)") End If Next y Next x CountNumColor = NumEQ End Function このプログラムで問題がありましたらぜひとも教えてください。GetPicxel以外の間違いに気づいた人がいた場合もご意見をお待ちしております。また、この質問で分からないことがございましたら遠慮なく書き込んでください。気づき次第返答いたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

No.2の回答者です。 質問の関数内には見当たりませんが、以下のような、どのイメージファイルを対象とするかのインスタンスは作成してますでしょうか?  Dim myBitmap As New Bitmap("c:\Test.jpg")  言うまでもないとは思いますが、「c:\Test.jpg」部分は、実際判定したいファイルのパスに入替てください。  上記の文を入れておいて、その後以下の文を入れれば波線はでないかと思います。  If System.Drawing.Color.Black.ToArgb() = myBitmap.GetPixel(x, y).ToArgb() Then  Bitmapそのものを使うわけにはいかないので、「Bitmap」は「myBitmap」に「GetPixel(1, 1)」は「GetPixel(x, y)」に変えています。  「GetPixel(1, 1)」は、私がテストしたときのまま載せてしまったので・・・。    これでうまくいくかと思うのですが、どうでしょうか。

kisisuku
質問者

お礼

ありがとうございます。 波線のエラーは消えましたが、白と黒を半分ずつ読み込んで50%と50%という風にカウントする変な現象が起こるようになってしまいました。どうしたらいいでしょうか?変更後の内容は以下のプログラムです。 Function CountNumColor(ByRef DotWW As Long, ByRef DotHH As Long, ByRef CHECK_C As Long) As Integer Dim Form1 As Object Dim NumEQ As Double Dim NumNot As Long Dim x, y As Long Dim ChkColor As Color = Color.FromArgb(0) Dim myBitmap As New Bitmap("E:\2005\画像処理システム\黒.bmp") NumEQ = 0 NumNot = 0 System.Windows.Forms.Application.DoEvents() For x = 0 To DotHH - 1 For y = 0 To DotWW - 1 System.Windows.Forms.Application.DoEvents() ChkColor = myBitmap.GetPixel(x, y) If ChkColor.R = 0 And ChkColor.G = 0 And ChkColor.B = 0 Then NumEQ = NumEQ + 1 Else NumNot = NumNot + 1 Debug.Write("x,y,Val(Bitmap.GetPixel(x, y)") End If Next y Next x CountNumColor = NumEQ End Function なぜか心当たりはありますか?全部のプログラムを一旦載せた方がいいのでしょうか?

その他の回答 (3)

回答No.4

そうですね、見た感じは間違っていないようです。 しかし、この関数だと黒は判別してますが、白は判別してないと思いますよ。R=0;G=0;B=0の色かそれ以外かですよね。    全体のソースを送ってもらえば、確かにわかりやすいですが、「E:\2005\画像処理システム\黒.bmp」のファイルの中身のほうが気になります。    例えば、R=1;G=1;B=1の色でも、普通の人には真っ黒にしか見えないはずです。50対50と言われるとどうしてもタイルパターンの濃さがちょっと違うだけの黒が交互に並んでいるビットマップを想像してしまうのですが、どうでしょうか。  

kisisuku
質問者

お礼

回答ありがとうございます。 補足し忘れましたが、画像ははじめから白黒にした画像を使用していますw おかげさまで黒の画像を読み込むことができました。 ほんとにありがとうございます。

回答No.2

 No.1の回答者さんが最後におっしゃっているように Bitmap.GetPixel(x,y) の部分はColor構造体を戻り値として返すので、Long型との比較はできないはずです。  Val()は引数文字列を数値型に変えるので無理矢理 "Bitmap.GetPixel(x,y)"と文字列にして引数に入れれば、見た目エラーにはなりませんが、これではBitmap~自体が意味をなしません。    他にも方法はあるかもしれませんが、Color構造体どおしをArgbに変換して比較するとうまく判定できるはずです。黒だったら、 If System.Drawing.Color.Black.ToArgb() = Bitmap.GetPixel(1, 1).ToArgb() Then で、取得した色が同じく黒だったら、Trueを返します。  この場合の黒は「A=255,R=0,G=0,B=0」です。見た目黒でも引っかかってこない場合は、ARGB値を変えるか、幅を持たせる必要があるでしょう。    

kisisuku
質問者

お礼

ご返事ありがとうございます^^ このプログラムを組み込んで見たところ、組み込んだ部分のBitmap.GetPixelの部分が波線となりエラーになってしまいました。心当たりがございましたらぜひとも返信をお願いいたします。

  • mo_gu
  • ベストアンサー率51% (56/109)
回答No.1

Bitmapはあまり使わないのでわからないことが多いのですが 怪しそうなところをあげてみます。 If CHECK_C = Val("Bitmap.GetPixel(x,y)") Then Valのところを変更してみてください。 If CHECK_C = Val(Bitmap.GetPixel(x,y)) Then GetPixelはcolor構造体を返しますけど Valでチェックしたい色が取れるのでしょうか?

kisisuku
質問者

お礼

アドバイスありがとうございます。 改良後、また掲示いたしますので、御助言お願いいたします。  初心者に近いので詳しくは伝えられませんが、白黒の判別がうまくいかないだけで%ではしっかりと読み込んでいるようでした。  自分の作っているプログラム以外にVB.NETで白黒を判別する方法がありましたら、ヒント、もしくは助言のほどお願いいたします。

関連するQ&A

  • 困っています

    読み込んだ画像を白黒判別し、それぞれカウントするプログラムを作ったのですが、上手く機能してくれません。このプログラムについてどなたかわかる方、助言お願いします。間違っている箇所や気づいたこと等、何でもお願いします。 Function CountNumColor(ByRef DotWW As Long, ByRef DotHH As Long, ByRef CHECK_C As Long) As Integer  Dim Form1 As Object Dim NumEQ As Double Dim NumNot As Long Dim x, y As Long NumEQ = 0 NumNot = 0 System.Windows.Forms.Application.DoEvents() For x = 0 To DotHH - 1 For y = 0 To DotWW - 1 System.Windows.Forms.Application.DoEvents() If System.Drawing.Color.BlackToArgb() = Bitmap.GetPixel(x, y).ToArgb() Then NumEQ = NumEQ + 1 Else NumNot = NumNot + 1 Debug.Write("x,y,Val(Bitmap.GetPixel(x, y)") End If Next y Next x CountNumColor = NumEQ End Function

  • 簡単法知ってる人教えてください。

    ボタンを押して画像を読み込み、その画像をカウントするプログラムを考えたのですが、画像の絶対パスを取得するために毎回変更する部分ができてしまいました;; 誰か、どんな画像でも読み込める工夫を知ってる人がいたら教えてください。プログラムは↓ Function CountNumColor(ByRef DotWW As Long, ByRef DotHH As Long, ByRef CHECK_C As Long) As Integer Dim Form1 As Object Dim NumEQ As Double Dim NumNot As Long Dim x, y As Long Dim ChkColor As Color = Color.FromArgb(0) Dim myBitmap As New Bitmap("E:\2005\画像処理システム\無題.bmp") NumEQ = 0 NumNot = 0 System.Windows.Forms.Application.DoEvents() For x = 0 To DotHH - 1 For y = 0 To DotWW - 1 System.Windows.Forms.Application.DoEvents() ChkColor = myBitmap.GetPixel(x, y) If ChkColor.R = 0 And ChkColor.G = 0 And ChkColor.B = 0 Then NumEQ = NumEQ + 1 Else NumNot = NumNot + 1 Debug.Write("x,y,Val(Bitmap.GetPixel(x, y)") End If Next y Next x CountNumColor = NumEQ End Function このプログラムの”E:\2005\画像処理システム\無題.bmp”の部分を工夫してどんな画像でも読み込むことができることができるようにできないでしょうか? わかる人の知恵を貸してください><

  • エクセルVBAで2つの画像を比較したい

    こんにちは。VBAの初心者です。 エクセル2003のVBAを使って、シートに読み込んだ縦横24ピクセルの2つの画像(picA、picB)を比較したいと考えています。VBなどのページを参考に、APIのGetPixel関数を使えばなんとかなりそうだというところまではたどり着いて、以下のコードを組んでみたのですが、うまく動きません。 Private Declare Function GetPixel Lib "gdi32" _ (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Private Sub CommandButton1_Click() Dim picA As Image Dim picB As Image Dim p1 As Integer Dim p2 As Integer Dim ScreenhDC As Long For x = 1 To 24 For y = 1 To 24 p1 = picA.GetPixel(ScreenhDC, x, y) p2 = picB.GetPixel(ScreenhDC, x, y) If p1 <> p2 Then MsgBox "違う画像です" Exit Sub End If Next Next MsgBox "同じ画像です" End Sub 「p1 = picA.GetPixel(ScreenhDC, x, y)」のところで「実行時エラー'91': オブジェクト変数またはWithブロック変数が設定されていません。」というメッセージが出て止まってしまいます。解決法をご教示いただけませんでしょうか。 そもそもエクセルのVBAではAPIは使えないなどということはありますか?

  • VB6.0の参照渡し

    VC++6.0で作成したDLLへVBの配列を渡そうと思っています。 いくつかためしたのですが、 「配列引数は ByRef でなければなりません。」 というエラーがでてしまいます。 標準モジュール内の記述 Declare Function fncTest Lib "Test.dll" (ByRef test() As Long) As Long フォーム内 Private Sub Test_Click() dim test() as Long dim i as integer for i = 0 to 3 test(i) = i next i fncTest(Test()) End Sub とりあえず、こんな形でかいてみましたが、 Sub内のtest()の宣言方法、使用法等ご指導お願いします。

  • Excel2003VBAでクリップボードにあるビットマップの操作について

    Excel2003VBAにおいてクリップボードにあるビットマップの画像の任意の1pxの色を、 ペイントのスポイトツールのように取得するマクロを作成したいのですが GetPixelという関数で画像の任意1pxの色を取得できる所までは調べられたのですが、 それをクリップボードの画像で使用することができませんでした。 以下は、GetPixel関数を試してみた時のソースになります。 '------------------------------------------------------------------ Option Explicit Declare Function GetDesktopWindow Lib "user32" () As Long Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal Y As Long) As Long Sub ピクセル色獲得() Dim hwnd As Long Dim hdc As Long hwnd = GetDesktopWindow() hdc = GetWindowDC(hwnd) Debug.Print Hex(GetPixel(hdc, 100, 200)) End Sub '------------------------------------------------------------------ 上記ソースで任意1pxの色を取得できたため クリップボードの画像の色を取得するマクロを下記のように作成しました。 '--------------------------------------------------------------- Option Explicit Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal Y As Long) As Long Sub クリップボードピクセル色獲得() Dim CB As Variant Dim i As Long CB = Application.ClipboardFormats Debug.Print Hex(GetPixel(CB, 100, 200)) End Sub '--------------------------------------------------------------- 型が一致しません と言われ動きません。 以上です、よろしくお願いいたします。

  • 画像の90度回転表示の処理時間を短縮したい

    今、PictureBox に読み込んだ画像を90度回転して別の PictureBox に表示していますが、処理にとても時間がかかっています。(480×640ピクセルを右90度変換するのに約3.5秒) もっと処理が早くなる方法があれば教えてください。よろしくお願いします。 ---現在の処理(Picture1 → Picture2)--- Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long Private Declare Function SetPixelV Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long Dim p1sw  As Long  'Picture1.ScaleWidth Dim p1sh  As Long  'Picture1.ScaleHeight Dim x1    As Long Dim y1    As Long Dim c    As Long  'カラーコード Dim hDC1  As Long  'Picture1.hDC Dim hDC2  As Long  'Picture2.hDC Dim X    As Long Dim Y    As Long '縦横サイズを逆転する With Picture1   p1sw = .ScaleWidth   p1sh = .ScaleHeight   hDC1 = .hdc End With With Picture2   .Height = Picture1.Width   .Width = Picture1.Height   hDC2 = .hdc End With p1sw = p1sw - 1 p1sh = p1sh - 1 'ピクチャを90度回転 For X = 0 To p1sw         'Picture1のX座標   y1 = X   For Y = 0 To p1sh       'Picture1のY座標     x1 = p1sh - Y     c = GetPixel(hDC1, X, Y) 'カラー情報の取得     '取得したカラーを指定位置に設定する     If c <> -1 Then Call SetPixelV(hDC2, x1, y1, c)   Next Y Next X # OSはWindows95、VB6.0(SP5)を使用しています。

  • マウスのある個所の色

    お世話になります よろしくお願いします Pictureboxをクリックされたときに そのPictureboxがクリックされた箇所の色を16進数で取得したいのですが うまくいきません どこが間違っているのか教えてもらえないでしょうか? ソースは Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Type POINTAPI x As Long y As Long End Type Private Sub Picture1_Click() Dim Poi As POINTAPI Dim iro As Long GetCursorPos Poi iro = GetPixel(Me.Picture1.hdc, Poi.x, Poi.y) Me.Label2.Caption = Poi.x Me.Label3.Caption = Poi.y Me.Label1.Caption = iro CloseHandle (Me.Picture1.hdc) End Sub GetPixcelの引数に-1しか入りません あと、もし数値で取れたとして それを16進数にする方法を教えてください よろしくお願いします

  • VB2005での画像処理

    各ピクセルの色情報を取得し,そのままコピーするプログラムです. 同じ大きさのPictureBox1とPictureBox2,それとButton1があります. エラーや警告は出ませんが,Button1をクリックしてもまったく動きません. 最終的にはPictureBox1を画像処理してPictureBox2に結果を表示させたいのですが,そのままコピーも出来ないため原因を探しています. A = picture1.GetPixel(i, j).ToArgb() picture2.SetPixel(i, j, color.FromArgb(A)) ではだめなのでしょうか.ご教授ください. -----以下プログラム------ Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim i As Integer Dim j As Integer Dim A As Integer Dim picture1 As New Bitmap(PictureBox1.Image) Dim picture2 As New Bitmap(PictureBox2.Image) For j = 0 To PictureBox1.Width - 1 For i = 0 To PictureBox1.Height - 1 A = picture1.GetPixel(i, j).ToArgb() picture2.SetPixel(i, j, color.FromArgb(A)) Next Next End Sub

  • VB.NETにおける二値化処理の高速化

    いつも参考にさせて頂いております。 現在、VB.NET(VS2003/.NET Framework1.1)を使用して画像の二値化処理のプログラムを作成しております。 処理する事は簡単で、ビットマップファイルのRED要素を取り出し、閾値内なら白に変換して二値化するプログラムです。 以下がそのプログラムです。 ----- '変換する前の画像をファイルから読み込む Dim img1 As System.Drawing.Bitmap = New System.Drawing.Bitmap(filepath) '変換後のビットマップ Dim img2 As System.Drawing.Bitmap = New System.Drawing.Bitmap(img1.Width, img2.Height) '二値化処理 Dim b As Byte For i = 0 To img1.Width - 1 For j = 0 To img1.Height - 1 b = img1.GetPixel(i, j).R If b >= 閾値下限 And b <= 閾値上限 Then img2.SetPixel(i, j, Color.White) Else img2.SetPixel(i, j, Color.Black) End If Next Next PictureBox1.Image = img ----- これで処理は出来るのですが、ファイルが大きい場合は、非常に時間が掛かってしまいます。処理速度はCPUの速度にもよると思うのですが、できるだけ高速化したのですが、何かよい知恵があればご教授頂けると助かります。よろしくお願いいたします。 XP Pro SP2/VS2003/VB.NET/.NET Framework1.1

  • VB.NETのグラフィック描画で困っています

    VB.NETでのグラフィックの記述方法ですが 何かをクリックすると描画させるのではなく 単にあるsubプロシージャ内でグラフィックを描画させる記述する方法として pictureBox1.Image=New Bitmap(PictureBox1.width,pictureBox1.Height) Dim g As Graphics = Graphics.FromImage(PictureBox1.Image) を教えていただきました。そこで private sub xy_keisan() '座標を計算させるプロシージャ disp_x() 'x座標に目盛りを表示させるプロシージャ disp_Y() 'xの目盛り数によってY座標の位置を変えて表示させるプロシージャ end sub private sub disp_x() pictureBox1.Image=New Bitmap(PictureBox1.width,pictureBox1.Height) Dim g As Graphics = Graphics.FromImage(PictureBox1.Image) g.DrawLine(****** end sub private sub disp_y() pictureBox1.Image=New Bitmap(PictureBox1.width,pictureBox1.Height) Dim g As Graphics = Graphics.FromImage(PictureBox1.Image) g.DrawLine(****** end sub のような記述(引数とか細かい所は端折っています)ですとdisp_yは描画されていますが,disp_xは消えてしまいます。 pictureBox1.Image=New Bitmap(PictureBox1.width,pictureBox1.Height) が消えてしまう原因だとおもって宣言場所を変えてみましたが同じです 逆にこれが無いと描画させることが出来なくなります。 これの意味も今ひとつ判りません よろしくお願い致します

専門家に質問してみよう