#c# #wpf #bitmapsource #writablebitmap
#c# #wpf #bitmapsource #writablebitmap
Вопрос:
Я пытаюсь скопировать часть BitmapSource в WritableBitmap.
Пока это мой код:
var bmp = image.Source as BitmapSource;
var row = new WriteableBitmap(bmp.PixelWidth, bottom - top, bmp.DpiX, bmp.DpiY, bmp.Format, bmp.Palette);
row.Lock();
bmp.CopyPixels(new Int32Rect(top, 0, bmp.PixelWidth, bottom - top), row.BackBuffer, row.PixelHeight * row.BackBufferStride, row.BackBufferStride);
row.AddDirtyRect(new Int32Rect(0, 0, row.PixelWidth, row.PixelHeight));
row.Unlock();
Я получаю «Исключение ArgumentException: значение не попадает в ожидаемый диапазон». в строке CopyPixels
.
Я попытался поменять местами row.PixelHeight * row.BackBufferStride
с row.PixelHeight * row.PixelWidth
, но затем я получаю сообщение об ошибке, в котором говорится, что значение слишком низкое.
Я не смог найти ни одного примера кода, использующего эту перегрузку CopyPixels
, поэтому я прошу о помощи.
Спасибо!
Ответ №1:
Какую часть изображения пытаются скопировать? измените ширину и высоту в целевом ctor, а также ширину и высоту в Int32Rect, а также первые два параметра (0,0), которые являются смещениями x amp; y в изображении. Или просто оставьте, если хотите скопировать все целиком.
BitmapSource source = sourceImage.Source as BitmapSource;
// Calculate stride of source
int stride = source.PixelWidth * (source.Format.BitsPerPixel 7) / 8;
// Create data array to hold source pixel data
byte[] data = new byte[stride * source.PixelHeight];
// Copy source image pixels to the data array
source.CopyPixels(data, stride, 0);
// Create WriteableBitmap to copy the pixel data to.
WriteableBitmap target = new WriteableBitmap(
source.PixelWidth,
source.PixelHeight,
source.DpiX, source.DpiY,
source.Format, null);
// Write the pixel data to the WriteableBitmap.
target.WritePixels(
new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
data, stride, 0);
// Set the WriteableBitmap as the source for the <Image> element
// in XAML so you can see the result of the copy
targetImage.Source = target;
Комментарии:
1. Спасибо! Я вроде как надеялся, что смогу скопировать непосредственно из BitmapSource в WritableBitmap… Теперь мне интересно, для чего на самом деле предназначена эта перегрузка копипикселей…
2. Перегрузка rectangle скопирует растровое изображение в Int32Rect, поэтому не так полезно передавать его в WritableBitmap. Если вам нужно что-то действительно короткое и вы хотите скопировать все изображение целиком: цель Writable BITMAP = новая Writable BITMAP (рис. 1. Источник как BitmapSource); Рис. 2.Источник = цель;
3. А если мне нужна только часть BitmapSource (мне нужен прямоугольник с относительно небольшой высотой и такой же шириной)?
4. Если вы используете один байт на пиксель, это приведет к сбою. Правильное вычисление шага «байт на пиксель» равно (BitsPerPixel 7) / 8
5. В ответе есть
width * (bitsPerPixel 7) / 8
. Не следует ли вместо этогоwidth * ((bitsPerPixel 7) / 8)
?