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

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

新規登録して質問してみよう
ただいま回答率
85.40%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

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

Q&A

解決済

3回答

383閲覧

WPF でZXing.NET を使用して1次元バーコードを作成したいのですが画像が滲みます

byori

総合スコア72

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

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

0グッド

0クリップ

投稿2024/07/22 01:11

編集2024/07/22 06:13

実現したいこと

ZXing.NET を利用してバーコードを作成しています。作製自体はできていると考えていますが、印刷すると白い部分に黒いドットのようなノイズと言うか滲みが出ています。

このため、バーコードリーダーでは読めるレベルですが、スキャンして認識させようとすると多くの場合、読めません。

 「多くの場合」とは、自分が作成したZXing.NETで作製した読み込み処理のコードでは読んでくるようです。これを別のアプリ(他者納品の為、不明)で読ませると読めないとのことでした。

このバーコードの線をシャープにしたい。

発生している問題・分からないこと

イメージ説明

エラーメッセージ

error

1エラーメッセージは出ていません。

該当のソースコード

C#

1 // バーコード生成の設定 2 var writer = new BarcodeWriter 3 { 4 Format = BarcodeFormat.CODE_128, //.CODE_128, 5 Options = new EncodingOptions 6 { 7 Height = 100, 8 Width = 250, 9 Margin = 1 10 //PureBarcode = true // 純粋なバーコードを生成 11 }, 12 Renderer = new BitmapRenderer() 13 { 14 //DpiX = 300, 15 //DpiY = 300, 16 Background = System.Drawing.Color.White, // 背景色を白に設定 17 Foreground = System.Drawing.Color.Black // 前景色を黒に設定 18 } 19 }; 20 int w = 250; 21 int h = 100; 22 23 using (var bitmap = writer.Write(content)) 24 { 25 // ビットマップを200x60にリサイズ 26 using (var resizedBitmap = new System.Drawing.Bitmap(w, h)) 27 { 28 using (var graphics = System.Drawing.Graphics.FromImage(resizedBitmap)) 29 { 30 // アンチエイリアシングを無効化 31 graphics.InterpolationMode = InterpolationMode.NearestNeighbor; 32 graphics.SmoothingMode = SmoothingMode.None; 33 graphics.PixelOffsetMode = PixelOffsetMode.None; 34 graphics.CompositingQuality = CompositingQuality.HighQuality; 35 graphics.DrawImage(bitmap, 0, 0, w, h); 36 } 37 38 // BitmapをBitmapImageに変換 39 BitmapImage bitmapImage; 40 using (var memory = new MemoryStream()) 41 { 42 resizedBitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Png); 43 memory.Position = 0; 44 45 bitmapImage = new BitmapImage(); 46 bitmapImage.BeginInit(); 47 bitmapImage.StreamSource = memory; 48 bitmapImage.CacheOption = BitmapCacheOption.OnLoad; 49 bitmapImage.EndInit(); 50 } 51 // アンチエイリアシングを無効化 52 RenderOptions.SetEdgeMode(bitmapImage, EdgeMode.Aliased); 53 // Imageコントロールに表示 54 BarcodeImage.Source = bitmapImage; 55 } 56 }

追加のソースコード

C#

1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 } 7 8 private void button1_Click(object sender, RoutedEventArgs e) 9 { 10 FixedDocument documents = new FixedDocument(); 11 12 Canvas.SetTop(BarcodeImage, 10); 13 Canvas.SetLeft(BarcodeImage, 10); 14 documents = CreatePageModel.CreatePages(BarcodeImage); 15 16 // プレビュー表示 17 PreviewControl.DoPrint(documents); 18 } 19 } 20 21 22 23 class PrintPageModelBase 24 { 25 public object Header { get; set; } 26 public object Body { get; set; } 27 public int PageNumber { get; set; } 28 } 29 class CreatePageModel : PrintPageModelBase 30 { 31 public static FixedDocument CreatePages(System.Windows.Controls.Image img) 32 { 33 FixedDocument doc = new FixedDocument(); 34 35 PageContent pc = new PageContent(); 36 pc.Child = PrintDocPrintPage(img); 37 doc.Pages.Add(pc); 38 39 return doc; 40 } 41 public static FixedPage PrintDocPrintPage(System.Windows.Controls.Image img) 42 { 43 Canvas canvas = new Canvas(); 44 FixedPage fPage = new FixedPage(); 45 System.Windows.Controls.Page page = new Page(); 46 47 System.Windows.Controls.Image image = new System.Windows.Controls.Image(); 48 image.Source = img.Source; 49 50 canvas.Children.Add(image); 51 52 fPage = CreateFixedPage(page); 53 fPage.Children.Add(canvas); 54 55 return fPage; 56 } 57 private static FixedPage CreateFixedPage(Page page) 58 { 59 FixedPage fixpage = new FixedPage(); 60 { 61 try 62 { 63 Frame fm = new Frame(); 64 fm.Content = page; 65 66 FixedPage.SetLeft(fm, 0); 67 FixedPage.SetTop(fm, 0); 68 fixpage.Children.Add(fm); 69 70 // ピクセル値を求める計算式は、 用紙の一辺の長さ[mm] × 解像度[dpi] ÷ 25.4 です。 71 page.Height = 1118; // 8.27 * 96; // 793.92 72 page.Width = 794; // 使用する用紙の幅をセットする 73 74 System.Windows.Size sz = new System.Windows.Size(page.Width, page.Height); 75 76 fixpage.Width = page.Width; 77 fixpage.Height = page.Height; 78 fixpage.Measure(sz); 79 fixpage.Arrange(new Rect(new System.Windows.Point(), sz)); 80 fixpage.UpdateLayout(); 81 } 82 catch (Exception ex) 83 { 84 MessageBox.Show(ex.Message); 85 } 86 87 return fixpage; 88 } 89 } 90 } 91 92 93 94 internal class PreviewControl 95 { 96 static Window preView; 97 public static string printerMei; 98 /// <summary> 99 /// 用紙サイズ 100 /// </summary> 101 public static PageMediaSize PageMediaSize { get; set; } // = new PageMediaSize(PageMediaSizeName.ISOA4); 102 /// <summary> 103 /// カラーモード 104 /// </summary> 105 public static OutputColor? OutputColor { get; set; } = System.Printing.OutputColor.Color; //.;Monochrome 106 /// <summary> 107 /// 印刷部数 108 /// </summary> 109 public static int? CopyCount { get; set; } = 1; 110 // public static System.Windows.Size PageSize { get; set; } 111 112 113 114 public static void DoPrint(FixedDocument doc) 115 { 116 try 117 { 118 //https://stackoverflow.com/questions/23785720/pdfsharp-missing-the-xps-namespace/23786446#23786446 119 //https://nathanpjones.com/2013/03/output-to-pdf-in-wpf-for-free/ 120 121 // プレビュー表示すると MemoryStream?のエラーで回避できないので直接印刷 122 DocumentViewer viewer = new DocumentViewer { Document = doc }; 123 viewer.CommandBindings.Add(new CommandBinding(ApplicationCommands.Print, PrintExecute)); 124 preView = new Window() 125 { 126 Title = "印刷", 127 WindowStartupLocation = WindowStartupLocation.CenterScreen, 128 Content = viewer, 129 }; 130 preView.ShowDialog(); 131 } 132 catch (Exception ex) 133 { 134 MessageBox.Show(ex.Message); 135 } 136 } 137 138 private static void PrintExecute(object sender, ExecutedRoutedEventArgs e) 139 { 140 e.Handled = true; 141 PrintDialog dlg = new PrintDialog(); 142 143 // 用紙向き(縦) 144 dlg.PrintTicket.PageOrientation = System.Printing.PageOrientation.Portrait; // Landscape 145 146 // 以下でも変わらない 147 // dlg.PrintTicket.PageResolution = new PageResolution(9600, 9600); 148 149 PrintTicket pt = dlg.PrintTicket; 150 // 用紙サイズ 151 pt.PageMediaSize = PageMediaSize; 152 153 // トレイの設定 154 pt.InputBin = InputBin.Manual; // ここで InputBin を設定してください。例えば、InputBin = InputBin.Custom など 155 156 // カラーモード 157 pt.OutputColor = OutputColor; 158 // 印刷部数(同じものがもう一部必要) 159 pt.CopyCount = CopyCount; 160 // Create a local print server 161 LocalPrintServer ps = new LocalPrintServer(); 162 163 System.Windows.Xps.XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(dlg.PrintQueue); 164 FixedDocument doc = (FixedDocument)((DocumentViewer)sender).Document; 165 doc.PrintTicket = pt; // dlg.PrintTicket; 166 xpsdw.Write(doc, dlg.PrintTicket); 167 168 preView.Close(); 169 } 170 }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

調べた結果で該当のコードになりました。

補足

VS2019 WPF C# Windows11 ZXing.NET 0.16.9 .NET Framework 4.8

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

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

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

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

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

hqf00342

2024/07/22 01:27

「白い部分に黒いドットのようなノイズと言うか滲み」というのはどの段階で発生しているのですか。  (1) ZXing.NETが生成した画像  (2) 上記画像をWPF内で拡大しImageコントロールに表示したBitmap  (3) プリンタで印刷したときの画像
byori

2024/07/22 02:09

画像を <Image Name="BarcodeImage" HorizontalAlignment="Center" VerticalAlignment="Center"/> で表示した時も線が少しぼやけてる感じがしますが、明確なのは印刷後です。添付の写真は、印刷したものをスキャンしています。 プリンタは、リコーの IMC300 という複合機です。
byori

2024/07/22 02:13

質問の1-3で言うと(1)になるのでしょうか? Image コントロールでは、そのまま表示です。拡大によるボヤケ?とも考えた時があり Options = new EncodingOptions { Height = 200, Width = 400, と大きくして試しましたが、変化ありませんでした。
YAmaGNZ

2024/07/22 05:01

WindowsForm .NET Framework 4.8、ZXing.NET 0.16.9 にて上記コードの生成されたバーコード画像のbitmapと200x60にリサイズ後のresizedBitmapを見てみましたがバーコード部分は白と黒以外の色は見つけることができませんでした。(GetPixelにて確認しました) 描画前のBitmapクラスでの話なのでWPFとの違いも関係ないと思っています。 本当に(1)の生成した画像にぼやけがあるのか再度確認されてはどうでしょうか? 例えば生成した画像をそのままビットマップファイルに保存して、それを別のソフト(ペイントやエクセル等)にて同じ大きさで印刷したりしてみて違いがあるのかなど確認されてはどうでしょうか?
byori

2024/07/22 06:14

YAmaGNZ様お世話になります。 > 例えば生成した画像をそのままビットマップファイルに保存して ワードに張り付け印刷してみました。 めっちゃ!きれいに印刷できました!望んでいるレベルでした。 と言うことは印刷の過程で何か問題があるということでしょうか? 印刷のコードを追記しました。
guest

回答3

0

お世話になります。
すみません、回答に気付いていませんでした。

試しましたが、おっしゃる通りジャギーが目立ちますね。特に細い白い線がまだ厳しいかもしれません。
でも、作成直後のバーコードを保存して別のアプリで印刷・・・
が解決への糸口になりました。バーコード自体は問題ないことがわかりました。
これが大ヒントでした。ありがとうございます。

using (var bitmap = writer.Write(content)) { bitmap.Save("xxxxx.jpg", ImageFormat.Jpeg);

投稿2024/07/23 04:14

byori

総合スコア72

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

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

0

自己解決

自己レスです。

ご指導いただいた方法での確認は、バーコードを作成直後のビットマップをそのまま(WPF用の加工をしない)保存した状態で印刷すると線のギザギザやボケがなくきれいにできました。

ハッキリしていませんが、以下での処理(MemoryStream()かも!?)をナシにして
BitmapImage bitmapImage;
using (var memory = new MemoryStream())
{

}

     ↓ のように変更

var bitmap = writer.Write(content); using (var bmp2 = TransformToMono(bitmap)) { bmp2.Save("test.bmp", ImageFormat.Bmp); } // メモリー上で画像変換するとぼやけるので、保存して読み返してみる BitmapImage bmpImage = new BitmapImage(); try { using (FileStream stream = File.OpenRead("test.bmp")) { bmpImage.BeginInit(); bmpImage.CacheOption = BitmapCacheOption.OnLoad; // ここが重要 bmpImage.StreamSource = stream; bmpImage.EndInit(); stream.Close(); } // アンチエイリアシングを無効化 RenderOptions.SetEdgeMode(bmpImage, EdgeMode.Aliased); // Imageコントロールに表示 BarcodeImage.Source = bmpImage; }

一旦保存して読み直すという、「なんでそんな面倒な・・・」と思われる方法で対処することにしました。
ループで作製すると別の問題が起きそうですが、対処したいと思います。

とりあえず、印刷してもぼやけることなく出来たので一応の解決とさせていただきました。

投稿2024/07/23 04:05

byori

総合スコア72

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

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

0

印刷処理のImageに対してのスケーリングを指定してはどうでしょうか。

C#

1 public static FixedPage PrintDocPrintPage(System.Windows.Controls.Image img) 2 { 3 Canvas canvas = new Canvas(); 4 FixedPage fPage = new FixedPage(); 5 System.Windows.Controls.Page page = new Page(); 6 7 System.Windows.Controls.Image image = new System.Windows.Controls.Image(); 8 image.Source = img.Source; 9 10 // この行を追記 11 // スケーリングをニアレストネイバー法とする 12 RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor); 13 14 canvas.Children.Add(image); 15 16 fPage = CreateFixedPage(page); 17 fPage.Children.Add(canvas); 18 19 return fPage; 20 }

ニアレストネイバー法であればバーコードの拡大には向いていると思います。
ただ、バーコード下の文字はジャギーが目立つ結果になるかと思います。

投稿2024/07/23 01:01

YAmaGNZ

総合スコア10383

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

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

byori

2024/07/23 04:17

お世話になります。 すみません、回答に気付いていませんでした。 試しましたが、おっしゃる通りジャギーが目立ちますね。特に細い白い線がまだ厳しいかもしれません。 でも、作成直後のバーコードを保存して別のアプリで印刷・・・ が解決への糸口になりました。バーコード自体は問題ないことがわかりました。 これが大ヒントでした。ありがとうございます。 using (var bitmap = writer.Write(content)) { bitmap.Save("xxxxx.jpg", ImageFormat.Jpeg);
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問