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

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

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

Re[2]: QRコードの読取について


(過去ログ 141 を表示中)

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

■82583 / inTopicNo.1)  QRコードの読取について
  
□投稿者/ 夜叉丸 (37回)-(2017/01/19(Thu) 08:39:48)

分類:[.NET 全般] 

環境は以下になります。
Windwos7 sp1
Visual Studio 2013 C# .Net

BMP に描画されているQRコードのデコードをしようとしています。

こちらを参考に以下のプログラムを作成しました。
http://d.hatena.ne.jp/katsuraghi/20110101/1293890533

ZXing.Net.0.14.0.0.zip をダウンロードして
その中にある
zxing.wp7.1.dll を参照に追加しています。

private void button1_Click(object sender, EventArgs e)
{
 Reader reader = new ZXing.MultiFormatReader();
 ZXing.Result result = null;
 Bitmap bmp = new Bitmap(pbx.Image);
 MemoryStream mms = new MemoryStream();
 bmp.Save(mms, ImageFormat.Bmp);
 Byte[] dats = mms.GetBuffer();
 mms.Close();
 LuminanceSource source = new RGBLuminanceSource(bmp, bmp.Width, bmp.Height);
 BinaryBitmap binaryBitmap = new BinaryBitmap(new ZXing.Common.GlobalHistogramBinarizer(source));
 result = reader.decode(binaryBitmap);
 string OutputText = result.Text;
 MessageBox.Show(OutputText);
}


RGBLuminanceSource の引数の1番目が byte[] になっているため
bmp が渡せないので byte[] に変換しています。

string OutputText = result.Text;
にて result = null のためエラーが発生します。

何かお気づきの点があれば教えてください。
引用返信 編集キー/
■82589 / inTopicNo.2)  Re[1]: QRコードの読取について
□投稿者/ 魔界の仮面弁士 (1065回)-(2017/01/19(Thu) 11:12:11)
2017/01/19(Thu) 11:27:20 編集(投稿者)

No82583 (夜叉丸 さん) に返信
> ZXing.Net.0.14.0.0.zip をダウンロード
> 何かお気づきの点があれば教えてください。
ZXing.Net を使うのは初めてですが、分かる範囲で回答します。


> zxing.wp7.1.dll を参照に追加しています。
.\net何某\zxing.dll ではなく
.\wp7.1\zxing.wp7.1.dll を使っているという事は
デスクトップアプリケーションではなく、
Windows Phone OS 7.1 向けのアプリケーションでしょうか。
(VS2013 って、WP7.1 SDK に対応しているんでしたっけ?)


>  Bitmap bmp = new Bitmap(pbx.Image);
pbx というのは、System.Windows.Forms.PictureBox の事でしょうか。

『BMP に描画されているQRコード』とのことでしたが、事前に
PictureBox に Bitmap を割り当てているのでしょうか。

もしも Bitmap を割り当てず、Paint イベントや CreateGraphics などで
描画しているだけなら、Image プロパティからは QR コードの
画像情報を得ることは出来ません。



ひとまず、zxing.dll の場合は下記で動作することを確認しています。
zxing.wp7.1.dll ではこの方法が使えません。

private void Form1_Load(object sender, EventArgs e)
{
  pictureBox1.Load("https://upload.wikimedia.org/wikipedia/ja/6/60/Qr_code.png");
}

private void button1_Click(object sender, EventArgs e)
{
  string resultText = null;
  using (var bmp = new System.Drawing.Bitmap(pictureBox1.Image))
  {
    var reader = new ZXing.BarcodeReader() { AutoRotate = true };
    var result = reader.DecodeMultiple(bmp) ?? new ZXing.Result[0];
    resultText = string.Join("\r\n", result.Select(r => r.Text));
  }
  MessageBox.Show(resultText);
}



>  Byte[] dats = mms.GetBuffer();
GetBuffer ではなく ToArray を使いましょう。
データのコピーが発生してしまいますが、その方が確実です。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=30706&KLOG=55

MemoryStream.GetBuffer は、格納されたデータではなく、
そのデータを保持するための作業領域を返しますので、
実際のデータは、その中の一部分だけです。

データ長は Length プロパティで読み出せますが、
データの先頭から始まるとは限りませんし。
(今回は 0 バイト目になるでしょけれども)

データのコピーを伴わせたくない場合には、GetBuffer の代わりに、
TryGetBuffer を用いることができます(要 .NET 4.6 以上)。

この方法なら、バッファー内の何バイト目から何バイト目を得れば
良いのかを、部分配列(ArraySegment<byte>)を通じて得られます。
今回使うことは無いと思いますけれども。


>  LuminanceSource source = new RGBLuminanceSource(bmp, bmp.Width, bmp.Height);
> RGBLuminanceSource の引数の1番目が byte[] になっているため
> bmp が渡せないので byte[] に変換しています。
その割には、Byte[] な dats ではなく、Bitmap な bmp を渡しているような…。

それと、RGBLuminanceSource のコンストラクタ引数の説明を見てみると、
byte[] rgbRawBytes パラメーターが『It supports a byte array with 3 bytes per pixel (RGB24).』
であると書かれていますので、色数情報が不明瞭なビットマップファイルを
ヘッダーも含めて渡すのでは駄目なのかもしれません。
引用返信 編集キー/
■82591 / inTopicNo.3)  Re[2]: QRコードの読取について
□投稿者/ 夜叉丸 (38回)-(2017/01/19(Thu) 14:20:25)
No82589 (魔界の仮面弁士 さん) に返信

> .\net何某\zxing.dll ではなく
> .\wp7.1\zxing.wp7.1.dll を使っているという事は
> デスクトップアプリケーションではなく、
> Windows Phone OS 7.1 向けのアプリケーションでしょうか。
> (VS2013 って、WP7.1 SDK に対応しているんでしたっけ?)

いくつかフォルダがあって、wで始まってるからWindows用かと思ってました。
あらためて、[net4.0]の中の zxingdll, zxing.presentation.dll を追加しました。
結果は同じでした。


> pbx というのは、System.Windows.Forms.PictureBox の事でしょうか。
>
> 『BMP に描画されているQRコード』とのことでしたが、事前に
> PictureBox に Bitmap を割り当てているのでしょうか。
>
> もしも Bitmap を割り当てず、Paint イベントや CreateGraphics などで
> 描画しているだけなら、Image プロパティからは QR コードの
> 画像情報を得ることは出来ません。
>

ピクチャーボックスにはQRコードが表示されています。
また、datas の配列数が 142794 なのでデータがあると思うのですが


>
> ひとまず、zxing.dll の場合は下記で動作することを確認しています。
> zxing.wp7.1.dll ではこの方法が使えません。
>
> private void Form1_Load(object sender, EventArgs e)
> {
>   pictureBox1.Load("https://upload.wikimedia.org/wikipedia/ja/6/60/Qr_code.png");
> }
>
> private void button1_Click(object sender, EventArgs e)
> {
>   string resultText = null;
>   using (var bmp = new System.Drawing.Bitmap(pictureBox1.Image))
>   {
>     var reader = new ZXing.BarcodeReader() { AutoRotate = true };
>     var result = reader.DecodeMultiple(bmp) ?? new ZXing.Result[0];
>     resultText = string.Join("\r\n", result.Select(r => r.Text));
>   }
>   MessageBox.Show(resultText);
> }
>

このコードをそのまま置き換えるとうまくいきました。
サンプルがまちがっているのかな?


> GetBuffer ではなく ToArray を使いましょう。
> データのコピーが発生してしまいますが、その方が確実です。
> http://bbs.wankuma.com/index.cgi?mode=al2&namber=30706&KLOG=55
>
> MemoryStream.GetBuffer は、格納されたデータではなく、
> そのデータを保持するための作業領域を返しますので、
> 実際のデータは、その中の一部分だけです。
>
> データ長は Length プロパティで読み出せますが、
> データの先頭から始まるとは限りませんし。
> (今回は 0 バイト目になるでしょけれども)
>
> データのコピーを伴わせたくない場合には、GetBuffer の代わりに、
> TryGetBuffer を用いることができます(要 .NET 4.6 以上)。
>
> この方法なら、バッファー内の何バイト目から何バイト目を得れば
> 良いのかを、部分配列(ArraySegment<byte>)を通じて得られます。
> 今回使うことは無いと思いますけれども。
>

GetBuffer を ToArray でやってみましたがやっぱり駄目でした

>
> その割には、Byte[] な dats ではなく、Bitmap な bmp を渡しているような…。
>

あ、本当ですね。プログラムでは dats になっていました。
bmp の時のタイミングでコピペしてしまったと思います。

> それと、RGBLuminanceSource のコンストラクタ引数の説明を見てみると、
> byte[] rgbRawBytes パラメーターが『It supports a byte array with 3 bytes per pixel (RGB24).』
> であると書かれていますので、色数情報が不明瞭なビットマップファイルを
> ヘッダーも含めて渡すのでは駄目なのかもしれません。

要するにこの方法では使えないということですよね。


でも、動作できたのでよかったです。
ありがとうございました。

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


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -