Проблема с загрузкой изображения из массива байтов

#c# #wpf

#c# #wpf

Вопрос:

Я столкнулся со странным поведением при загрузке изображения из массива байтов, полученного из потока. Большинство изображений верны, я бы сказал, 99% из них. Но я видел до сих пор два раза что-то подобное ниже. Изображение в середине отображается как набор случайных пикселей, а не как реальное изображение.

Изображение может быть правильно загружено в другое клиентское приложение (sliverlight), но я не могу этого показать. В клиенте WPF у меня что-то вроде этого:

Изображение в середине отображается как набор случайных пикселей,

У кого-нибудь была такая проблема? Или любая идея, что может вызвать это? Может быть, мне следует посмотреть на стороне сервера (изображение отображается в другом, более старом клиенте, и код для загрузки мне известен).

Код выглядит так:

     public async Task<ImageCreatePictureBox> CreatePictureBox(IBaseObj pmIBaseObj, IObj pmObj)
    {
        var lcContainer = new Grid
        {
            Width = pmObj.PresObj.Width,
            Height = pmObj.PresObj.Height
        };
        var gridBorder = new Border();

        CustomImg imageControl = null;
        FrameworkElement lcFrameworkElement = lcContainer;

        if (!(pmIBaseObj is ImageBaseObj lcImageBaseObj))
            return new ImageCreatePictureBox(null, lcContainer, lcFrameworkElement, pmObj);

        if (!lcImageBaseObj.CustomBitMap)
        {
            try
            {
                var bitmapImage = BitmapImageHelper.ByteArrayToBitmapSource(lcImageBaseObj.Image, lcImageBaseObj.ImageWidth, lcImageBaseObj.ImageHeight);

                imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
                {
                    Source = bitmapImage,
                    Height = lcImageBaseObj.Height,
                    Width = lcImageBaseObj.Width
                };
            }
            catch (Exception e)
            {
                var src = new BitmapImage(new Uri(Helper.GetPathToImage("dummy")));
                imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
                {
                    Source = src,
                    Height = lcImageBaseObj.Height,
                    Width = lcImageBaseObj.Width
                };
                Helper.WriteToDebug(e);
            }
        }
        else
        {
            try
            {
                var bitmapImage = BitmapImageHelper.ByteArrayToBitmapSource(lcImageBaseObj.Image, lcImageBaseObj.ImageWidth, lcImageBaseObj.ImageHeight);

                imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
                {
                    Source = bitmapImage,
                    Height = lcImageBaseObj.Height,
                    Width = lcImageBaseObj.Width
                };
            }
            catch (Exception e)
            {
                if (imageControl == null)
                    imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj);
                var src = new BitmapImage(new Uri(Helper.GetPathToImage("dummy")));
                imageControl = new CustomImg(pmIBaseObj.Width, pmIBaseObj.Height, pmObj)
                {
                    Source = src,
                    Height = lcImageBaseObj.Height,
                    Width = lcImageBaseObj.Width
                };
                Helper.WriteToDebug(e);
            }
        }

        (...)
        
        return new ImageCreatePictureBox(imageControl, lcContainer, lcFrameworkElement, pmObj);
    }



    public static BitmapSource ByteArrayToBitmapSource(Byte[] BArray, int imgWidth, int imgHeight)
    {
        try
        {
            var width = imgWidth;
            var height = imgHeight;
            var dpiX = 90d;
            var dpiY = 90d;
            var pixelFormat = PixelFormats.Pbgra32;
            var bytesPerPixel = (pixelFormat.BitsPerPixel   7) / 8;
            var stride = bytesPerPixel * width;

            var bitmap = BitmapSource.Create(width, height, dpiX, dpiY, pixelFormat, null, BArray, stride);
            return bitmap;
        }
        catch (Exception e)
        {
            return BytesToBitmapImage(BArray);
        }
    }
 

Комментарии:

1. Если это работает в 99% случаев, я бы ожидал, что это будет какая-то разница между 1%, которые терпят неудачу, и 99%, которые работают. Вы уверены, что исходные данные верны?

2. @JonasH, я думаю, это нормально, потому что в более старой версии программного обеспечения, написанного на Silverlight, подобной проблемы нет, каждое изображение отображается правильно. Но, возможно, мне следует проверить это еще раз, как оно там сделано и как данные отправляются / принимаются. Спасибо за ваш комментарий.

3. В данном конкретном случае это не имеет значения, но шаг должен вычисляться как stride = (width * pixelFormat.BitsPerPixel 7) / 8;

4. Кроме того, пожалуйста, попробуйте удалить ненужные части вашего кода. Я думаю, нам не нужно видеть класс ImageCreatePictureBox и многое другое.

5. Также неясно, почему вы создаете BitmapSource с разрешением 90 точек на дюйм вместо стандартного 96.