c#phone 8.1改变jpeg质量

时间:2014-11-19 21:46:59

标签: c# windows-runtime windows-phone-8.1

我想从相机中捕捉图像,减小尺寸并降低质量。

到目前为止这是我的功能:

private async void BildSpeichern(object sender, RoutedEventArgs e)
{
    MenuFlyoutItem FO = sender as MenuFlyoutItem;
    StorageFile datei = await StorageFile.GetFileFromPathAsync(_viewmodel.DateiPfad);

    string neuerDateiName=datei.Name + "___" + FO.CommandParameter.ToString();
    await datei.RenameAsync(neuerDateiName);
    _viewmodel.DateiPfad = datei.Path;

    using (var sourceStream = await datei.OpenAsync(FileAccessMode.ReadWrite))
    {
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapEncoder.JpegEncoderId, sourceStream);


        uint oriWidth = decoder.PixelWidth;
        uint oriHeight = decoder.PixelHeight;

        uint tarWidth;
        uint tarHeight;

        if (oriWidth > oriHeight)
        {
            tarWidth = 1024;
            tarHeight = (uint)((float)tarWidth / (float)oriWidth * (float)oriHeight);
        }
        else
        {
            tarHeight = 1024;
            tarWidth = (uint)((float)tarHeight / (float)oriHeight * (float)oriWidth);
        }

        InMemoryRandomAccessStream IS = new InMemoryRandomAccessStream();
        BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(IS, decoder);
        decoder = null;
        encoder.BitmapTransform.ScaledWidth = tarHeight;
        encoder.BitmapTransform.ScaledHeight = tarWidth;
        await encoder.FlushAsync();

    }
    await datei.CopyAsync(Windows.Storage.KnownFolders.PicturesLibrary,"TEST.JPG",NameCollisionOption.ReplaceExisting);

    FotoVorschau.Visibility = Visibility.Visible;
    FotoAnzeige.Visibility = Visibility.Collapsed;
    AufnahmeStackpanel.Visibility = Visibility.Visible;
    VorschauStackpanel.Visibility = Visibility.Collapsed;
    FotoAnzeige.Source = null;
    _viewmodel.DateiPfad = null;
}

我唯一缺少的就是压缩,或者让我们更好地说明生成的JPEG图像质量下降。

我发现的唯一示例使用System.Drawing,但这在Windows Phone 8.1项目中无法使用...有人知道如何实现这一目标吗?

编辑: 这是我函数的新部分,但Image不会调整大小并且不会被压缩:

using (var sourceStream = await datei.OpenAsync(FileAccessMode.ReadWrite))
            {
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream);


                uint oriWidth = decoder.PixelWidth;
                uint oriHeight = decoder.PixelHeight;

                uint tarWidth;
                uint tarHeight;

                if (oriWidth > oriHeight)
                {
                    tarWidth = 1024;
                    tarHeight = (uint)((float)tarWidth / (float)oriWidth * (float)oriHeight);
                }
                else
                {
                    tarHeight = 1024;
                    tarWidth = (uint)((float)tarHeight / (float)oriHeight * (float)oriWidth);
                }

                var propertySet = new Windows.Graphics.Imaging.BitmapPropertySet();
                var qualityValue = new Windows.Graphics.Imaging.BitmapTypedValue(
                    0.6,
                    Windows.Foundation.PropertyType.Single
                    );

                propertySet.Add("ImageQuality", qualityValue);

                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, sourceStream, propertySet);
                PixelDataProvider pd = await decoder.GetPixelDataAsync();
                encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, oriWidth, oriHeight, decoder.DpiX, decoder.DpiY, pd.DetachPixelData());
                decoder = null;

                encoder.BitmapTransform.ScaledWidth = tarHeight;
                encoder.BitmapTransform.ScaledHeight = tarWidth;
                encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Cubic;

                await encoder.FlushAsync();
                sourceStream.Dispose();

            }

3 个答案:

答案 0 :(得分:3)

Robert提到的链接为我打开了该文章的HTML版本,但XAML one有一些很好的样本:

IAsyncOperation<BitmapEncoder> CreateEncoderWithEncodingOptionsAsync(
    Windows.Storage.Streams.IRandomAccessStream stream
    )
{
    var propertySet = new Windows.Graphics.Imaging.BitmapPropertySet();
    var qualityValue = new Windows.Graphics.Imaging.BitmapTypedValue(
        1.0, // Maximum quality
        Windows.Foundation.PropertyType.Single
        );

    propertySet.Add("ImageQuality", qualityValue);
    return Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(
        Windows.Graphics.Imaging.BitmapEncoder.JpegEncoderId,
        stream,
        propertySet
        );

    // Encoder is initialized with encoding options.
}

答案 1 :(得分:0)

值得看看以下内容:

http://msdn.microsoft.com/library/windows/apps/system.windows.media.imaging.extensions.savejpeg(v=vs.105).aspx

System.Windows.Media.Imaging命名空间中的Extensions.SaveJpeg方法。特别是这种方法的质量参数:

质量 键入:System.Int32 此参数表示JPEG照片的质量,范围在0到100之间,其中100是最佳照片质量。我们建议您不要低于70.因为JPEG图片质量会明显低于该级别。

然后可以使用以下代码调用它:

using (IsolatedStorageFileStream isostream = iso.CreateFile(strImageName)) 
{                    
    BitmapImage bitmap = new BitmapImage(); 
    bitmap.SetSource(stream); 
    WriteableBitmap wb = new WriteableBitmap(bitmap); 
    // Encode WriteableBitmap object to a JPEG stream. 
    Extensions.SaveJpeg(wb, isostream, wb.PixelWidth, wb.PixelHeight, 0, 85); 
    isostream.Close(); 
} 

这里有一些关于编码选项的额外信息,以及有关ImageQuality编码选项的更多详细信息。

http://msdn.microsoft.com/en-us/library/windows/apps/jj218354.aspx

答案 2 :(得分:0)

Filip的工作原理,但最后缺少一行代码:

std::string

您可以在this article

找到示例
map[std::string("keyString")]