我一直在看BitmapDecoder
and BitmapEncoder
,但我不知道如何将数据从 jpg 解码器获取到 png 编码器。我发现的唯一接近的是BitmapEncoder::CreateForTranscodingAsync()
,但那是两种图像格式相同的情况。
4 回答
您可以像这样使用给定的图像格式(编解码器)读取像素数据并将它们写入 BitmapEncoder(对不起,这是 C# 而不是 C++,但它应该可以工作):
const string sourceFileName = "42.jpg";
StorageFolder imageFolder = Package.Current.InstalledLocation;
StorageFile imageFile = await imageFolder.GetFileAsync(sourceFileName);
using (IRandomAccessStream imageStream = await imageFile.OpenReadAsync())
{
// Read the pixel data
BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(imageStream);
BitmapTransform dummyTransform = new BitmapTransform();
PixelDataProvider pixelDataProvider = await bitmapDecoder.GetPixelDataAsync(
BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, dummyTransform,
ExifOrientationMode.RespectExifOrientation,
ColorManagementMode.ColorManageToSRgb);
byte[] pixelData = pixelDataProvider.DetachPixelData();
// Save the pixel data as PNG
const string resultImageFileName = "42.png";
StorageFile resultImageFile =
await ApplicationData.Current.LocalFolder.CreateFileAsync(
resultImageFileName, CreationCollisionOption.ReplaceExisting);
using (IRandomAccessStream resultImageStream =
await resultImageFile.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder bitmapEncoder = await BitmapEncoder.CreateAsync(
BitmapEncoder.PngEncoderId, resultImageStream);
bitmapEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore,
bitmapDecoder.OrientedPixelWidth, bitmapDecoder.OrientedPixelHeight,
96, 96, pixelData);
await bitmapEncoder.FlushAsync();
}
}
唯一的问题是如何确定有关文件格式(在本例中为 PNG)的像素格式、alpha 模式和 DPI 的最佳设置。我从现有的 PNG 文件中确定了像素模式。设置 BitmapAlphaMode.Ignore 是因为 JPEG 不支持透明度。因此,在 PNG 文件中启用 alpha 通道是没有意义的。宽度和高度设置为 BitmapDecoder 的 OrientedPixelWidth 和 OrientedPixelHeight,因为我在阅读时启用了 EXIF 方向。DPI 针对目标系统设置得最好。96 是 Windows 的默认值。
使用 ImageMagick 库怎么样?
http://www.imagemagick.org/script/index.php
Theres a C++ API ... in the documentation我在2分钟的搜索中找到了这个:
#include
using namespace std;
using namespace Magick;
int main(int argc,char **argv)
{
InitializeMagick(*argv);
// Read GIF file from disk
Image image( "giraffe.gif" );
// Write to BLOB in JPEG format
Blob blob;
image.magick( "JPEG" ) // Set JPEG output format
image.write( &blob );
[ Use BLOB data (in JPEG format) here ]
return 0;
}
就个人而言,我可以推荐这个库与 ImageMagick 一起工作得相当广泛(尽管使用 C API ......)
编辑:您可以将图像写入内存块并将字节传递给编码器......
利用
BitmapDecoder::GetPixelDataAsync(BitmapPixelFormat, BitmapAlphaMode, BitmapTransform, ExifOrientationMode, ColorManagementMode)
然后
BitmapEncoder::SetPixelData(BitmapPixelFormat pixelFormat, BitmapAlphaMode alphaMode, unsigned int width, unsigned int height, double dpiX, double dpiY, array<unsigned char>^ pixels)
我对Windows-8编程不熟悉,只是看文档,是不是就这么简单?
Stream imageStreamSource = new FileStream("myimage.jpg" ...);
JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
FileStream stream = new FileStream("myimage.png", FileMode.Create);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Interlace = PngInterlaceOption.Off;
encoder.Frames.Add(bitmapSource);
encoder.Save(stream);