質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1343閲覧

ZXing を使ってシールにバーコードを印刷すると例外が発生する

byori

総合スコア71

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2023/01/06 02:15

編集2023/01/07 02:03

WPF で ZXing を使ってシールにバーコードとデータを印刷するアプリを作成しています。
シールは、約B5サイズの不定形で縦5マス、横10マス(1シールのサイズは、21ミリ×23ミリ)です。
シールに印刷する(プレビュー表示)すること自体はできていますが、例外が発生します。
バーコードを作成しないとエラーがでないのでこの部分が怪しいと思いますが、回避策などあれば教えてください。
エラーで表示しているパスは、バーコード作成時に参照していないのでなぜこのようなメッセージがでるのかもわかりません。それともどこかプログラム内で指定などしていないと起きない事象ですか?

発生している問題・エラーメッセージ

System.IO.FileNotFoundException: 'ファイル 'C:\Users\xxxxx\OneDrive\ドキュメント\Visual Studio 2019\Projects\...\Debug\image' が見つかりませんでした。' この例外は、最初にこの呼び出し履歴 System.IO.__Error.WinIOError(int, string) System.IO.FileStream.Init(string, System.IO.FileMode, System.IO.FileAccess, int, bool, System.IO.FileShare, int, System.IO.FileOptions, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES, string, bool, bool, bool) System.IO.FileStream.FileStream(string, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare)      :(文字数制限によりエラーの一部を割愛しました) で、 そういうことじゃないとわかっているけど「image」フォルダーを指定位置に作ってみると下記になります System.UnauthorizedAccessException: 'パス 'C:\Users\xxxxx\OneDrive\ドキュメント\Visual Studio 2019\Projects\...\bin\Debug\image' へのアクセスが拒否されました。' この例外は、最初にこの呼び出し履歴 System.IO.__Error.WinIOError(int, string) System.IO.FileStream.Init(string, System.IO.FileMode, System.IO.FileAccess, int, bool, System.IO.FileShare, int, System.IO.FileOptions, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES, string, bool, bool, bool) System.IO.FileStream.FileStream(string, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare)     :

このエラーは、Zxing でバーコードを作成すると起きているようです。

該当のソースコード

labelPos  シールの位置情報 double yoko = 25 * 96 / 25.4; // シールのサイズ・マージン込み(横) double tate = 25 * 96 / 25.4; // シールのサイズ・マージン込み(縦) for (int tateSu = 0; tateSu < 5; ++tateSu) // 印刷位置縦(1-5) { for (int yokoSu = 0; yokoSu < 10; ++yokoSu) // 印刷位置横(1-10) {     : if (labelPos.座標X.Length > 0 && labelPos.座標Y.Length > 0) { // コメント② if (double.TryParse(labelPos.座標X, out result)) x = result; if (double.TryParse(labelPos.座標Y, out result)) y = result; if (double.TryParse(labelPos.文字Size, out result)) size = result; double haba = width - (width * x); // 印刷する文字の幅 canvas.Children.Add(LabelBox("文字データ", x + (yoko * yokoSu), y + (tate * tateSu), size, haba)); ↑について割愛しました。 } try { if (labelPos.labelBarcodeX.Length > 0 && labelPos.labelBarcodeY.Length > 0) { // バーコード if (double.TryParse(labelPos.labelBarcodeX, out result)) // 座標X (labelPos.labelBarcodeX) x = result; if (double.TryParse(labelPos.labelBarcodeY, out result)) // 座標Y (labelPos.labelBarcodeY) y = result; canvas.Children.Add(LabelImg(itm, x + (yoko * yokoSu), y + (tate * tateSu), 0)); } } catch (Exception ex) { MessageBox.Show(ex.Message); }    // バーコードを作成 private static Image LabelImg(LabelData item, double x, double y, double size) { BitmapFrame img; img = Helper.BarcodeHelper.BarcodeCreateForLabel("文字データ"); var image = new System.Windows.Controls.Image(); image.Source = img; Canvas.SetTop(image, y); Canvas.SetLeft(image, x); return image; } class BarcodeHelper { : /// <summary> /// ラベル用QRコード作製 /// </summary> /// <param name="data"></param> /// <returns></returns> internal static BitmapFrame BarcodeCreateForLabel(string data) { var barcode = new BarcodeWriter { Format = BarcodeFormat.QR_CODE, Options = new ZXing.QrCode.QrCodeEncodingOptions { ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.M, CharacterSet = "ISO-8859-1", // default //CharacterSet = "UTF-8", // japanese Width = 40, Height = 40, Margin = 1 }, }; //バーコード生成 BitmapFrame barcodebmp; using (var bmp = barcode.Write(data)) using (var ms = new MemoryStream()) { bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); barcodebmp = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); } return barcodebmp; }

試したこと

バーコードを作成すると上記エラーが発生します。バーコードを作成部分をコメントにするとエラーは出ません。

補足情報(FW/ツールのバージョンなど)

ZXing バージョン 0.16.8
Windows11 VS2019 C# WPF

----------------------- ここから追加事項です

試しています

教えていただいたサイトから「MemoryStreamをラップしたStreamクラスを作って Dispose時にMemoryStreamの参照を外すと・・・」をコピペしましたが、

イメージ説明

というエラーがいっぱい出ました。どうしたらいいですか?

上記について、自己レスです。クラスに必要なものを全部追加するよう書いてあったので追加したらエラーが消えました。確認はこれからです。

------------------- 追記②
作製した using (var stream = new WrappingStream(new MemoryStream())) クラスでBitmapFrameを作成するとサイズが1になりイメージが表示されません。
どこがダメなところか教えてください。

C#

1 internal static /*BitmapImage*/BitmapFrame BarcodeCreateForLabel(BarcodeFormat cODE_128, string falco) 2 { 3 var barcode = new BarcodeWriter 4 { 5 Format = BarcodeFormat.QR_CODE, 6 Options = new ZXing.QrCode.QrCodeEncodingOptions 7 { 8 ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.M, 9 CharacterSet = "ISO-8859-1", // default 10 //CharacterSet = "UTF-8", // japanese 11 Width = 40, 12 Height = 40, 13 Margin = 1 14 }, 15 }; 16 17 BitmapFrame barcodebmp; 18 using (var bmp = barcode.Write(falco)) 19 using (var stream = new WrappingStream(new MemoryStream())) 20 { 21 bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); 22 barcodebmp = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 23 24 /* 25 var bitmap = new BitmapImage(); 26 bitmap.BeginInit(); 27 bitmap.StreamSource = stream; 28 bitmap.CacheOption = BitmapCacheOption.OnLoad; 29 bitmap.EndInit(); 30 // bitmap.Freeze(); ここが有効だと「この Freezable はフリーズできません。」というエラーがでます 31 return bitmap;*/ 32 } 33 34 return barcodebmp; 35 } 36 37 38 // ラッパークラス 39 // このコード真ん中辺の「//...(中略)...」より追加しました。エラー回避のため 40 public class WrappingStream : Stream 41 { 42 Stream m_streamBase; 43 44 45 public WrappingStream(Stream streamBase) 46 { 47 if (streamBase == null) 48 { 49 throw new ArgumentNullException("streamBase"); 50 } 51 m_streamBase = streamBase; //渡したStreamを内部ストリームとして保持 52 } 53 54 //Streamクラスのメソッドをオーバーライドして、内部ストリームの同じメソッドをそのまま呼ぶだけ 55 public override Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) 56 { 57 ThrowIfDisposed(); 58 return m_streamBase.ReadAsync(buffer, offset, count, cancellationToken); 59 } 60 public new Task<int> ReadAsync(byte[] buffer, int offset, int count) 61 { 62 ThrowIfDisposed(); 63 return m_streamBase.ReadAsync(buffer, offset, count); 64 } 65 //...(中略)... 66 67 public override long Length { get; } 68 public override void SetLength(long value) 69 { 70 ThrowIfDisposed(); 71 //return m_streamBase.SetLength(value); 72 } 73 public override bool CanRead { get; } 74 public override int Read(byte[] buffer, int offset, int count) 75 { 76 ThrowIfDisposed(); 77 return m_streamBase.Read(buffer, offset, count); 78 } 79 //public virtual int Read(Span<byte> buffer) 80 //{ 81 // ThrowIfDisposed(); 82 // return m_streamBase.Read(buffer); 83 //} 84 public override long Position { get; set; } 85 public override void Write(byte[] buffer, int offset, int count) 86 { 87 ThrowIfDisposed(); 88 } 89 public override bool CanWrite { get; } 90 public override long Seek(long offset, System.IO.SeekOrigin origin) 91 { 92 ThrowIfDisposed(); 93 return m_streamBase.Seek(offset, origin); 94 } 95 public override void Flush() 96 { 97 ThrowIfDisposed(); 98 } 99 public override bool CanSeek { get; } 100 101 102 protected override void Dispose(bool disposing) 103 { 104 if (disposing) 105 { 106 m_streamBase.Dispose(); 107 m_streamBase = null; //disposeしたら内部ストリームをnullにして参照を外す 108 } 109 base.Dispose(disposing); 110 } 111 private void ThrowIfDisposed() 112 { 113 if (m_streamBase == null) 114 { 115 throw new ObjectDisposedException(GetType().Name); 116 } 117 } 118 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

byori

2023/01/07 02:07

kikukiku 様お世話になります。 サイトを参照して WrappingStream クラスを作成しましたが画像のサイズが1になってしまします。 そのコードは質問の最下部に追記しました。ラッパーは初めてなので手探りで書いてみましたが、どこか違っているのかわかりません。ご指摘いただけると助かります。
guest

回答1

0

自己解決

MemoryStream クラスの問題との指摘を受け参照サイトより WrappingStream 派生クラスを試しましたが、ビットマップが正しく変換されず(サイズが(1, 1)になってしまう)修正方法もわからなかったので、MemoryStream の問題なら別の方法で変換すれば!?とおもい下記のように書き換えました

WPF(C#)

1 BitmapFrame barcodebmp; 2 using (var bmp = barcode.Write(data)) 3 using (var ms = new MemoryStream()) 4 { 5 bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); 6 barcodebmp = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 7 } 8 return barcodebmp; 9 10   ↓ 11 12 using (var bitmap = barcode.Write(data)) 13 { 14 // 表示 15 BitmapSource image; 16 IntPtr hbitmap = bitmap.GetHbitmap(); 17 image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hbitmap, 18 IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); 19 DeleteObject(hbitmap); 20 21 return image; 22 } 23 24 [System.Runtime.InteropServices.DllImport("gdi32.dll")] 25 public static extern bool DeleteObject(IntPtr hObject);

すぐにはエラーがないようなのでこれで様子見てみます。

投稿2023/01/10 00:16

byori

総合スコア71

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問