我正在尝试调整我的 UWP 应用程序中的图像大小。大多数情况下,附加代码都有效,但有时 await encoder.FlushAsync();
会抛出 ArgumentException
。
我已经前往 MSDN ( https://msdn.microsoft.com/en-us/library/windows/apps/windows.graphics.imaging.bitmapencoder.bitmaptransform.aspx ),他们告诉我(在“备注”处):
If you try scale an image stored in an indexed pixel format using the BitmapTransform member, FlushAsync fails with HRESULT WINCODEC_ERR_INVALIDPARAMETER . Instead, you must use GetPixelDataAsync to obtain the scaled pixel data and then use SetPixelData to set it on the encoder.
我已经尝试这样做了,请参阅两条注释行(由于重复,这对我来说看起来有点不对)。在第二行(我尝试 SetPixelData
),编码器用 buffer allocated not sufficient
异常奖励我。
var decoder = await BitmapDecoder.CreateAsync(streamToReadFrom.AsStream().AsRandomAccessStream());
if (decoder.OrientedPixelHeight > height ||
decoder.OrientedPixelWidth > width)
{
var resizedStream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(resizedStream, decoder);
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
encoder.BitmapTransform.ScaledHeight = newHeight;
encoder.BitmapTransform.ScaledWidth = newWidth;
//"buffer allocated not sufficient"
// var pd = await decoder.GetPixelDataAsync(BitmapPixelFormat.Rgba16, BitmapAlphaMode.Ignore,
// encoder.BitmapTransform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage);
// encoder.SetPixelData(BitmapPixelFormat.Rgba16, BitmapAlphaMode.Ignore,
// decoder.OrientedPixelWidth, decoder.OrientedPixelHeight, decoder.DpiX, decoder.DpiY, pd.DetachPixelData());
// write out to the stream
// might fail cause https://msdn.microsoft.com/en-us/library/windows/apps/windows.graphics.imaging.bitmapencoder.bitmaptransform.aspx
await encoder.FlushAsync();
// Read out resizedStream and return
}
导致此问题的示例图像:http://www.spiegel.de/images/image-1028227-hppano-lqbn.jpg .此处进行单元测试:https://github.com/famoser/OfflineMedia/blob/master/Famoser.OfflineMedia.UnitTests/Presentation/ImageResizeTest.cs
如何避免 ArgumentException
?我如何知道图像采用“索引像素格式”,以及如何调整此格式的大小?
最佳答案
On the second line (where I try to SetPixelData) the Encoder rewards me with an buffer allocated not sufficient Exception.
这是因为当您 SetPixelData
时,像素数据与来自 GetPixelDataAsync
的像素数据不匹配。例如,您可以这样编写代码:
if (file != null)
{
BitmapImage bmp = new BitmapImage();
using(var imageStream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imageStream);
InMemoryRandomAccessStream pixelras = new InMemoryRandomAccessStream();
BitmapEncoder pixelencoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, pixelras);
BitmapTransform transform = new BitmapTransform();
transform.InterpolationMode = BitmapInterpolationMode.Fant;
transform.ScaledHeight = 400;
transform.ScaledWidth = 400;
var provider = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
transform,
ExifOrientationMode.RespectExifOrientation,
ColorManagementMode.DoNotColorManage);
var pixels = provider.DetachPixelData();
pixelencoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, 400,
400, decoder.DpiX, decoder.DpiY, pixels);
try
{
await pixelencoder.FlushAsync();
}
catch(Exception ex)
{
}
bmp.SetSource(pixelras);
img.Source = bmp;
}
}
How do I know an image is in an "indexed pixel format", and how can I resize this format too?
我找不到任何有效的方法来检测索引像素格式图像,但既然有人说
If you try scale an image stored in an indexed pixel format using the BitmapTransform member, FlushAsync fails with HRESULT WINCODEC_ERR_INVALIDPARAMETER . Instead, you must use GetPixelDataAsync to obtain the scaled pixel data and then use SetPixelData to set it on the encoder.
是使用catch the exception再使用SetPixelData
的方法,例如:
if (file != null)
{
BitmapImage bmp = new BitmapImage();
using(var imageStream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imageStream);
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
encoder.BitmapTransform.ScaledHeight = 400;
encoder.BitmapTransform.ScaledWidth = 400;
try
{
await encoder.FlushAsync();
bmp.SetSource(ras);
}
catch (Exception ex)
{
if (ex.HResult.ToString() == "WINCODEC_ERR_INVALIDPARAMETER")
{
InMemoryRandomAccessStream pixelras = new InMemoryRandomAccessStream();
BitmapEncoder pixelencoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, pixelras)
BitmapTransform transform = new BitmapTransform();
transform.InterpolationMode = BitmapInterpolationMode.Fant;
transform.ScaledHeight = 400;
transform.ScaledWidth = 400;
var provider = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
transform,
ExifOrientationMode.RespectExifOrientation,
ColorManagementMode.DoNotColorManage);
var pixels = provider.DetachPixelData();
pixelencoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, 400,
400, decoder.DpiX, decoder.DpiY, pixels);
try
{
await pixelencoder.FlushAsync();
bmp.SetSource(pixelras);
}
catch
{
}
}
}
img.Source = bmp;
}
}
关于c# - BitmapEncoder 刷新抛出参数异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38617761/