2

我一直在看BitmapDecoderand BitmapEncoder,但我不知道如何将数据从 jpg 解码器获取到 png 编码器。我发现的唯一接近的是BitmapEncoder::CreateForTranscodingAsync(),但那是两种图像格式相同的情况。

4

4 回答 4

2

您可以像这样使用给定的图像格式(编解码器)读取像素数据并将它们写入 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 的默认值。

于 2013-01-20T12:01:59.920 回答
2

使用 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 ......)

编辑:您可以将图像写入内存块并将字节传递给编码器......

于 2012-12-06T08:20:58.760 回答
0

利用

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)
于 2012-12-06T18:16:52.453 回答
0

我对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);
于 2012-12-06T16:51:04.307 回答