如何在C#WinRT / winmd中调整图像大小?

时间:2012-09-10 10:17:36

标签: c# windows-8 windows-runtime

我有一个简单的问题,但到目前为止我还没有找到答案:如何在C#WinRT / WinMD项目中调整jpeg图像的大小并将其保存为新的jpeg?

我正在开发Windows 8 Metro应用程序,用于从某个站点下载日常图像并将其显示在Live Tile上。问题是图像必须小于1024x1024且小于200kB,否则它将不会显示在图块上: http://msdn.microsoft.com/en-us/library/windows/apps/hh465403.aspx

如果我获得更大的图像,如何调整它以适应Live Tile?我正在考虑简单的调整大小,如宽度/ 2和高度/ 2,同时保持宽高比。

这里的具体要求是代码必须作为Windows运行时组件运行,因此WriteableBitmapEx库在这里不起作用 - 它仅适用于常规WinRT项目。 WriteableBitmapEx甚至还有一个分支作为winmd项目,但还远没有准备好。

5 个答案:

答案 0 :(得分:18)

如何缩放和裁剪here

的示例
async private void BitmapTransformTest()
{
    // hard coded image location
    string filePath = "C:\\Users\\Public\\Pictures\\Sample Pictures\\fantasy-dragons-wallpaper.jpg";

    StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
    if (file == null)
        return;

    // create a stream from the file and decode the image
    var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);


    // create a new stream and encoder for the new image
    InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
    BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);

    // convert the entire bitmap to a 100px by 100px bitmap
    enc.BitmapTransform.ScaledHeight = 100;
    enc.BitmapTransform.ScaledWidth = 100;


    BitmapBounds bounds = new BitmapBounds();
    bounds.Height = 50;
    bounds.Width = 50;
    bounds.X = 50;
    bounds.Y = 50;
    enc.BitmapTransform.Bounds = bounds;

    // write out to the stream
    try
    {
        await enc.FlushAsync();
    }
    catch (Exception ex)
    {
        string s = ex.ToString();
    }

    // render the stream to the screen
    BitmapImage bImg = new BitmapImage();
    bImg.SetSource(ras);
    img.Source = bImg; // image element in xaml

}

答案 1 :(得分:10)

更简单的代码来重新调整图像大小,而不是裁剪。以下代码将图像重新调整为80x80

using (var sourceStream = await sourceFile.OpenAsync(FileAccessMode.Read))
{
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream);
    BitmapTransform transform = new BitmapTransform() { ScaledHeight = 80, ScaledWidth = 80 };
    PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
        BitmapPixelFormat.Rgba8,
        BitmapAlphaMode.Straight,
        transform,
        ExifOrientationMode.RespectExifOrientation,
        ColorManagementMode.DoNotColorManage);

    using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, destinationStream);
        encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, 80, 80, 96, 96, pixelData.DetachPixelData());                        
        await encoder.FlushAsync();
    }
}

Source

答案 2 :(得分:2)

这是更短的版本,没有访问像素数据的开销。

TableModel::lists('column1','column2','column3');

答案 3 :(得分:0)

我只花了最后一个半小时试图弄清楚这一个,我有一个JPG的字节数组并尝试给出的答案......我无法让它工作所以我提出了一个新的答案...希望这会帮助其他人...我正在将JPG转换为250/250像素

private async Task<BitmapImage> ByteArrayToBitmapImage(byte[] byteArray)
    {
        BitmapImage image = new BitmapImage();
        using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
        {
            using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
            {
                writer.WriteBytes((byte[])byteArray);
                writer.StoreAsync().GetResults();
            }
            image.SetSource(stream);
        }
        image.DecodePixelHeight = 250;
        image.DecodePixelWidth = 250;

        return image;            
    }

答案 4 :(得分:0)

如果你想要高质量的图像,那么添加 InterpolationMode = BitmapTransform中的BitmapInterpolationMode.Fant, 这是示例

`  public static async Task ResizeImage(Windows.Storage.StorageFile imgeTOBytes,int maxWidth,int maxHeight)         {

        using (var sourceStream = await imgeTOBytes.OpenAsync(FileAccessMode.Read))
        {
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream);

            double widthRatio = (double)maxWidth / decoder.OrientedPixelWidth;
            double heightRatio = (double)maxHeight / decoder.OrientedPixelHeight;

            double scaleRatio = Math.Min(widthRatio, heightRatio);
            uint aspectHeight = (uint)Math.Floor((double)decoder.OrientedPixelHeight * scaleRatio);
            uint aspectWidth = (uint)Math.Floor((double)decoder.OrientedPixelWidth * scaleRatio);

            BitmapTransform transform = new BitmapTransform() { InterpolationMode = BitmapInterpolationMode.Fant, ScaledHeight = aspectHeight, ScaledWidth = aspectWidth };
            PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
                BitmapPixelFormat.Rgba8,
                BitmapAlphaMode.Premultiplied,
                transform,
                ExifOrientationMode.RespectExifOrientation,
                ColorManagementMode.DoNotColorManage);

            using (var destinationStream = await imgeTOBytes.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, destinationStream);
                encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, aspectWidth, aspectHeight, 96, 96, pixelData.DetachPixelData());
                await encoder.FlushAsync();
            }
        }`