Показать захваченный файл JPEG - PullRequest
1 голос
/ 26 июля 2010

Я могу сохранить захваченное изображение со сканера штрих-кода, используя этот код:

        Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
        dlg.DefaultExt = ".jpg";
        dlg.Filter = "JPEG Images (.jpg)|*.jpg|All files (*.*)|*.*";
        if (dlg.ShowDialog() == true)
        {
            using (FileStream file = File.OpenWrite(dlg.FileName))
            {
                file.Write(e.ImageBuffer, 0, e.ImageSize);
            }
        }

Однако я хотел бы отобразить захваченное изображение с помощью WPF, но получаю искаженное изображение.

private void _barcodeScannerInstance_SavePhotoEvent(object sender, ImageEventArgs e)
    {   
        SetBitmap(e.ImageBuffer, 350, 263, 96);

    }


 private void SetBitmap(byte[] image, int width, int height, int dpi)
      {
        MainWindow.Instance.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate()
        {
            BitmapSource bitmapSource = BitmapSource.Create(
            width, height, (double)dpi, (double)dpi, PixelFormats.Bgr24, null, image, ((width * 24 + 31) & ~31) >> 3);                

            HwModeScreen.BarcodeImageCanvas.Children.Clear();
            Image myImage = new Image();
            myImage.Width = HwModeScreen.BarcodeImageCanvas.ActualWidth;
            myImage.Height = HwModeScreen.BarcodeImageCanvas.ActualHeight;
            myImage.Stretch = Stretch.Fill;
            myImage.Source = bitmapSource;
            HwModeScreen.BarcodeImageCanvas.Children.Add(myImage);
        });

Вот изображение, которое я вижу.Это должно быть черно-белое изображение коробки kleenex.

alt text

Вот сохраненный файл jpg: alt text

Ответы [ 4 ]

2 голосов
/ 26 июля 2010

ты перепутал ширину и высоту?Вы уверены, что значение dpi правильное?

Я подозреваю, что вся проблема заключается в следующей строке:

        BitmapSource bitmapSource = BitmapSource.Create(
        width, height, (double)dpi, (double)dpi, PixelFormats.Bgr24, null, image, ((width * 24 + 31) & ~31) >> 3)

Что бы я сделал, чтобы отладить проблему, это записать изображение в файл иподтвердите все введенные данные.Используйте photoshop, paint.net, свойства файла ... Вы уверены, что работаете с растровым форматом?Вы уверены, что работаете с 24 битами на пиксель?Вы уверены, что у вас правильные значения высоты и ширины, и вы вводите значения в правильный аргумент

О чем эта строка и зачем вы это делаете?Я немного подозрительно((ширина * 24 + 31) & ~ 31) >> 3)

По сути, я смотрю на это так, что вы подаете в битовую библиотеку поток битов ... она не знаетчто это за биты, но он будет пытаться создать изображение из информации, которую вы ему предоставляете: биты на пиксель, размер и т. д. Если вы дадите ему неверную информацию, он создаст поврежденное изображение, как вы показали.

Я немного подозреваю, что проблема не в ширине и высоте;даже если вы смешаете эти два значения - я думаю, что вы получите хотя бы часть первого ряда пикселей для правильной визуализации.Я вижу статический / шум / снег, который говорит мне, что есть что-то в том, как поток битов был интерпретирован - он отображается как случайные черные и белые.

Еще одна вещь: в вашей экранной шапке ясм цветэто еще один намек на то, что в ваших предположениях об изображении есть что-то неверное.Значения должны, вероятно, от 1 до 256 (я думаю, 8 бит на пиксель?). Я бы попытался создать черно-белое растровое изображение на 8 бит на пиксель.Каким-то образом библиотека считает, что это цветное изображение.

Я только что заметил, что вы принимаете JPEG.JPEG - это формат с потерями - я бы предположил, что у вас получится растровое изображение или изображение TIFF.дважды проверьте, что вы действительно получаете изображение JPEG (проверьте документацию API штрих-кода)

1 голос
/ 26 июля 2010

Алгоритм сжатия JPEG совершенно не подходит для типа изображения, которое вы снимаете.Он хорошо работает с фотографиями, плохо работает с изображениями, содержащими тонкие линии.Небольшие артефакты, создаваемые сжатием, затрудняют правильное сканирование штрих-кода.

Вы не видите поле Kleenex, потому что пишете необработанные байты изображения.Вам нужно использовать кодировщик изображений.Я рекомендую вам использовать класс PngBitmapEncoder.GifBitmapEncoder также должен работать, так как вам не нужно много цветов, он создает файлы меньшего размера.Фрагмент кода, который показывает, как использовать кодировщик: доступен здесь .

0 голосов
/ 27 июля 2010

Я использовал jpeg-декодер для решения проблемы.

  private void SetBitmap(byte[] image, int width, int height, int dpi)
  {
    MainWindow.Instance.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate()
    {
        BMemoryStream ms = new MemoryStream(image);
        JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        BitmapSource bitmapSource = decoder.Frames[0];               

        HwModeScreen.BarcodeImageCanvas.Children.Clear();
        Image myImage = new Image();
        myImage.Width = HwModeScreen.BarcodeImageCanvas.ActualWidth;
        myImage.Height = HwModeScreen.BarcodeImageCanvas.ActualHeight;
        myImage.Stretch = Stretch.Fill;
        myImage.Source = bitmapSource;
        HwModeScreen.BarcodeImageCanvas.Children.Add(myImage);
    });
0 голосов
/ 26 июля 2010

это, вероятно, искажает

myImage.Stretch = Stretch.Fill;
...