2

BitmapDecoderとを見てきましたが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)に関して、ピクセル形式、アルファモード、およびDPIの最適な設定を決定する方法です。既存のPNGファイルからピクセルモードを決定しました。JPEGは透過性をサポートしていないため、BitmapAlphaMode.Ignoreが設定されます。したがって、PNGファイルでアルファチャネルを有効にすることは意味がありません。読み取り時にEXIF方向を有効にしたため、幅と高さはBitmapDecoderのOrientedPixelWidthとOrientedPixelHeightに設定されています。DPIは、ターゲットシステムに関して最適に設定されています。Windowsのデフォルトは96です。

于 2013-01-20T12:01:59.920 に答える
2

ImageMagick ライブラリを使用するのはどうですか?

http://www.imagemagick.org/script/index.php

Theres a C++ API ... inthe 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 に答える