我和我的朋友昨晚花了大部分时间在尝试处理metro应用中的一些图片上,几乎要把我们的头发都掉光了。我们使用共享Charm将图片导入应用程序,然后我想对它们进行一些其他操作,如裁剪图像并将其保存回appdata文件夹中。这证明非常令人沮丧。
我的问题是,在所有这些之后,"有没有正确的方法来完成这个任务,而不感觉像是在拼凑不匹配的拼图碎片?"
当使用共享多个图像到应用程序时,它们以
一些在线搜索表明,目前只有
当我稍后尝试重新打开文件时,我们遇到了最严重的问题。我做了类似之前的事情:
这段代码可以正常工作,但是如果图片被压缩,数据流会比预期的短,因此最终会出现越界异常。目前先假设它是未压缩的位图。
现在我已经有了图像数据,但我仍然有一个大问题。为了对其进行任何处理,我必须对其格式做出假设。我不知道它是rgba、rgb、abgr、bgra或其他格式。如果我猜错了,我的处理就会失败。我已经进行了几十次测试,结果得到的都是零字节和损坏的图像、颜色错误等问题。我希望从调用
我的问题是,在所有这些之后,"有没有正确的方法来完成这个任务,而不感觉像是在拼凑不匹配的拼图碎片?"
当使用共享多个图像到应用程序时,它们以
Windows.Storage.StorageFile
列表的形式出现。以下是用于处理此操作的一些代码。var storageItems = await _shareOperation.Data.GetStorageItemsAsync();
foreach (StorageFile item in storageItems)
{
var stream = await item.OpenReadAsync();
var properties = await item.Properties.GetImagePropertiesAsync();
var image = new WriteableBitmap((Int32)properties.Width, (Int32)properties.Height);
image.SetSource(stream);
images.Add(image);
}
一些在线搜索表明,目前只有
Windows.UI.Xaml.Media.Imaging.WriteableBitmap
能够让您访问图像中的像素数据。这个问题 包含了一个充满扩展方法的有用答案,可以将图像保存到文件中,因此我们使用了这些方法。当我稍后尝试重新打开文件时,我们遇到了最严重的问题。我做了类似之前的事情:
var files = await ApplicationData.Current.LocalFolder.GetFilesAsync();
foreach (var file in files)
{
var fileStream = await file.OpenReadAsync();
var properties = await file.Properties.GetImagePropertiesAsync();
var bitmap = new WriteableBitmap((Int32)properties.Width, (Int32)properties.Height);
bitmap.SetSource(fileStream);
System.IO.Stream stream = bitmap.PixelBuffer.AsStream();
这里有一个问题。如果我想从字节流中获取字节数,这个流有多长?
// CRASH! Length isn't supported on an IRandomAccessStream.
var pixels = new byte[fileStream.Length];
好的,请再试一次。
var pixels = new byte[stream.Length];
这段代码可以正常工作,但是如果图片被压缩,数据流会比预期的短,因此最终会出现越界异常。目前先假设它是未压缩的位图。
await _stream.ReadAsync(pixels, 0, pixels.Length);
好吧,你猜怎么着。尽管我使用bitmap.SetSource(fileStream);
来读取数据,但我的字节数组仍然全是零。我不知道为什么。如果我通过示例数据组将同样的bitmap
传递到我的UI中,图像就会正常显示。所以它显然在那个位图中有像素数据,但我为什么不能从bitmap.PixelBuffer
中读取它呢?为什么?
最后,这是实际起作用的方法。
var decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.PngDecoderId, fileStream);
var data = await decoder.GetPixelDataAsync();
var bytes = data.DetachPixelData();
/* process my data, finally */
} // end of that foreach I started a while ago
现在我已经有了图像数据,但我仍然有一个大问题。为了对其进行任何处理,我必须对其格式做出假设。我不知道它是rgba、rgb、abgr、bgra或其他格式。如果我猜错了,我的处理就会失败。我已经进行了几十次测试,结果得到的都是零字节和损坏的图像、颜色错误等问题。我希望从调用
await file.Properties.GetImagePropertiesAsync();
获取的properties
中能够找到一些信息,但没有运气。它只包含图像的宽度和高度以及其他一些无用的东西。最小的文档here。
那么,为什么这个过程如此痛苦?这只是反映了库目前的不成熟,我可以期待它变得更好吗?还是已经有某种标准方法来完成这个任务?我希望它像System.Drawing
那样容易。它提供了您所需的所有数据,并愉快地正确加载任何图像类型,而不需要让您自己处理流。