如何在 Xamarin.UWP 中调整大小和减小大小(使用压缩质量值)

Posted

技术标签:

【中文标题】如何在 Xamarin.UWP 中调整大小和减小大小(使用压缩质量值)【英文标题】:How to resize and reduce size (using a compression quality value) in Xamarin.UWP 【发布时间】:2021-02-19 18:47:45 【问题描述】:

我正在尝试编写一个函数来调整图像大小并使用压缩质量值对其进行压缩。我找到了一些有用的信息here和here和here,但我还是很困惑。

我正在使用 Dependency Services,并且已经成功地为 iosandroid 完成了它。下面是我用于ios的代码。

iOS

public byte[] DecodeImage(byte[] imgBytes, int regWidth, int regHeight, int compressionQuality)

    try
    
        NSData data = NSData.FromArray(imgBytes);
        var image = UIImage.LoadFromData(data);
        
        data = image.AsJPEG((nfloat) compressionQuality / 100);
        byte[] bytes = new byte[data.Length];
        System.Runtime.InteropServices.Marshal.Copy(data.Bytes, bytes, 0, Convert.ToInt32(data.Length));
        return bytes;
    
    catch (Exception ex)
    
        return null;
    

我想在我的 UWP 项目中为依赖服务复制相同的功能,非常感谢任何帮助。

这是我目前拥有的,但它不起作用。

public async Task<byte[]> DecodeImageAsync(string fileUri, int regWidth, int regHeight, int compressionQuality)

    byte[] returnVal;

    StorageFile file = await StorageFile.GetFileFromPathAsync(fileUri);

    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
    
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); //ConfigureAwait(false).;

        var qualityNum = (float)compressionQuality / 100;
        var propertySet = new BitmapPropertySet();
        var qualityValue = new BitmapTypedValue(
            qualityNum, // Maximum quality
            Windows.Foundation.PropertyType.Single
        );
        propertySet.Add("ImageQuality", qualityValue);

        var resizedStream = new InMemoryRandomAccessStream();

        BitmapEncoder en = await BitmapEncoder.CreateForTranscodingAsync(resizedStream, decoder);
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream,
            propertySet);


        double widthRatio = (double) regWidth / decoder.PixelWidth;
        double heightRatio = (double) regHeight / decoder.PixelHeight;

        double scaleRatio = Math.Min(widthRatio, heightRatio);

        if (regWidth == 0)
            scaleRatio = heightRatio;

        if (regHeight == 0)
            scaleRatio = widthRatio;

        uint aspectHeight = (uint) Math.Floor(decoder.PixelHeight * scaleRatio);
        uint aspectWidth = (uint) Math.Floor(decoder.PixelWidth * scaleRatio);

        encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;

        encoder.BitmapTransform.ScaledHeight = aspectHeight;
        encoder.BitmapTransform.ScaledWidth = aspectWidth;

        returnVal = new byte[stream.Size];
        await encoder.FlushAsync();
        stream.Seek(0);
        returnVal = new byte[stream.Size];
        var dr = new DataReader(stream.GetInputStreamAt(0));
        await dr.LoadAsync((uint)stream.Size);
        dr.ReadBytes(returnVal);
    
    return returnVal;

任何关于如何更改代码以调整图像大小以及压缩图像的想法将不胜感激。

【问题讨论】:

【参考方案1】:

终于弄明白了,我曾经在下面编写代码来实现这一点。

public async Task<byte[]> DecodeImageAsync(string fileUri, int regWidth, int regHeight, int compressionQuality)

    byte[] returnVal;

    try
    
        StorageFile file = await StorageFile.GetFileFromPathAsync(fileUri);

        using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
        
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
            SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();

            var qualityNum = (float) compressionQuality / 100;
            var propertySet = new BitmapPropertySet();
            var qualityValue = new BitmapTypedValue(
                qualityNum, 
                Windows.Foundation.PropertyType.Single
            );
            propertySet.Add("ImageQuality", qualityValue);

            var resizedStream = new InMemoryRandomAccessStream();

            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, resizedStream,
                propertySet);
            encoder.SetSoftwareBitmap(softwareBitmap);
            
            double widthRatio = (double) regWidth / decoder.PixelWidth;
            double heightRatio = (double) regHeight / decoder.PixelHeight;

            double scaleRatio = Math.Min(widthRatio, heightRatio);

            if (regWidth == 0)
                scaleRatio = heightRatio;

            if (regHeight == 0)
                scaleRatio = widthRatio;

            uint aspectHeight = (uint) Math.Floor(decoder.PixelHeight * scaleRatio);
            uint aspectWidth = (uint) Math.Floor(decoder.PixelWidth * scaleRatio);

            encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
            encoder.BitmapTransform.ScaledHeight = aspectHeight;
            encoder.BitmapTransform.ScaledWidth = aspectWidth;
            
            await encoder.FlushAsync();
            resizedStream.Seek(0);
            returnVal = new byte[resizedStream.Size];
            var dr = new DataReader(resizedStream.GetInputStreamAt(0));
            await dr.LoadAsync((uint) resizedStream.Size);
            dr.ReadBytes(returnVal);
        
    catch (Exception ex)
    
        return null;
    
    return returnVal;


【讨论】:

以上是关于如何在 Xamarin.UWP 中调整大小和减小大小(使用压缩质量值)的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 Xamarin.UWP 中 TableView TableSection 中的 TextSize 和大小写

如何在 Xamarin UWP 中更改 CommandBar Title 字体大小

磁盘上的图像文件大小(KB)随着Java中动态图像大小的调整(减小大小)而增加

应用程序的 Xamarin UWP 图标资产

如何调整 UIImage 的大小以减小上传图像的大小

如何在 Visual Studio 2017 中执行 Xamarin.uwp