#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.