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 }
回答1件
あなたの回答
tips
プレビュー