在 UWP 中使用模糊效果绘制图像未正确设置图像大小 [英] Drawing image using Blur effects in UWP is not properly set size for the image

查看:15
本文介绍了在 UWP 中使用模糊效果绘制图像未正确设置图像大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用滑块模糊图像.为此,我使用了 Win2D 模糊效果并在 CanvasControl 中绘制图像,并在实际图像上添加了画布.

我想使用滑块动态地将模糊效果应用于图像.但我不想将实际图像更改为模糊.因此,我在实际图像上使用了 Canvas 并使用模糊效果进行绘制.

问候,

巴拉蒂.

解决方案

在 UWP 中使用模糊效果绘制图像未正确设置图像大小

问题是CanvasControl的大小不适合图片源(Image: 960*640 CanvasControl:500*400).如果想让 CanvasControl 可以显示完整图像,请在调用 CanvasBitmap.LoadAsync 方法时设置可用的 dpi.对于我的测试,185 适合您的场景.

异步任务 CreateResourcesAsync(CanvasControl sender){cbi = await CanvasBitmap.LoadAsync(sender, "Flower1.jpg",185);}

更新

//var dpi = DisplayInformation.GetForCurrentView().LogicalDpi;var display = DisplayInformation.GetForCurrentView();//计算显示器的 dpivar dpi = Math.Sqrt(Math.Pow(display.ScreenWidthInRawPixels, 2) + Math.Pow(display.ScreenHeightInRawPixels, 2))/display.DiagonalSizeInInches;//获取 CanvasControl 英寸var inch = Math.Sqrt(Math.Pow(500, 2) + Math.Pow(400, 2))/dpi;//用图像大小计算最后的 dpivar lastdpi = Math.Sqrt(Math.Pow(960, 2) + Math.Pow(640, 2))/英寸;

更新 1

如果还可以设置CanvasControl 的大小和可以避免计算 Dpi 的图像大小.

更新 2

您还可以调整图片大小以适合 CanvasControl,请参考以下代码.

公共异步任务ResizeImage(StorageFile 文件,int reqWidth,int reqHeight){var memStream = new MemoryStream();使用 (Stream stream = await file.OpenStreamForReadAsync()){流.CopyTo(memStream);}IRandomAccessStream imageStream = memStream.AsRandomAccessStream();vardecoder = await BitmapDecoder.CreateAsync(imageStream);if (decoder.PixelHeight > reqHeight ||decoder.PixelWidth > reqWidth){使用(图像流){var resizedStream = new InMemoryRandomAccessStream();BitmapEncoder 编码器 = await BitmapEncoder.CreateForTranscodingAsync(resizedStream,decoder);double widthRatio = (double)reqWidth/decoder.PixelWidth;double heightRatio = (double)reqHeight/decoder.PixelHeight;double scaleRatio = Math.Min(widthRatio, heightRatio);如果(请求宽度== 0)比例比例 = 高度比例;如果(请求高度 == 0)比例比例 = 宽度比例;uint aspectHeight = (uint)Math.Floor(decoder.PixelHeight * scaleRatio);uint aspectWidth = (uint)Math.Floor(decoder.PixelWidth * scaleRatio);编码器.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;编码器.BitmapTransform.ScaledHeight = aspectHeight;编码器.BitmapTransform.ScaledWidth = aspectWidth;等待encoder.FlushAsync();返回调整大小的流;}}返回图像流;}

使用

异步任务 CreateResourcesAsync(CanvasControl sender){var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Flower1.jpg"));cbi = await CanvasBitmap.LoadAsync(sender, await ResizeImage(file, 500, 400));}

I want to blur the image using slider. For this, I have used Win2D Blur effects and draw the image in CanvasControl and added the canvas over the actual image.

Download sample here

Steps. 1. Added CanvasControl in button click. It will add a child to grid over the actual element 2. Change Slider to apply the blur 3. Issue: Image stretched and it's size too large and look like cropped. Not in the given size (500, 400)

[XAML]

<Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="7*"/>
                <ColumnDefinition Width="3*"/>
            </Grid.ColumnDefinitions>
        <Grid x:Name="imageGrid">
            <Image x:Name="image" Source="Flower1.jpg" Width="500" Height="400"
                       HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </Grid>
        <StackPanel Grid.Column="1" Orientation="Vertical">

            <Button Content="AddCanvas" Width="100" x:Name="addCanvas"
                        Click="AddCanvas_Click"/>

            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Blur" Width="100"/>
                <Slider x:Name="slider" Minimum="0" Maximum="5" Width="200"
                        ValueChanged="Slider_ValueChanged"/>
            </StackPanel>

        </StackPanel>
    </Grid>

[C#]

        bool isBlurred;
        GaussianBlurEffect blur = new GaussianBlurEffect();
        CanvasControl canv = new CanvasControl();
        CanvasBitmap cbi;

        public MainPage()
        {
            this.InitializeComponent();
        }
        private void AddCanvas_Click(object sender, RoutedEventArgs e)
        {
            canv.HorizontalAlignment = HorizontalAlignment.Left;
            canv.VerticalAlignment = VerticalAlignment.Top;
            canv.Draw += Canv_Draw;
            canv.CreateResources += Canv_CreateResources;
            canv.Height = 400;
            canv.Width = 500;

            imageGrid.Children.Add(canv);
        }

        private void Canv_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
        {
            args.DrawingSession.Units = CanvasUnits.Pixels;
            if (isBlurred)
            {
                args.DrawingSession.DrawImage(blur, new Rect(0, 0, 500, 400), new Rect(0, 0, 500, 400));
            }
        }

        private void Canv_CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
        {
            args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
        }
        async Task CreateResourcesAsync(CanvasControl sender)
        {
            cbi = await CanvasBitmap.LoadAsync(sender, "Flower1.jpg");
        }

        private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            isBlurred = true;
            blur.Source = cbi;
            blur.BlurAmount = (float)e.NewValue;
            canv.Invalidate();
        }

I would like to apply the Blur effects to the Image using slider dynamically. But i don't want to change the Actual image to Blur. So, I used Canvas over the Actual image and draw with Blur effect.

Regards,

Bharathi.

解决方案

Drawing image using Blur effects in UWP is not properly set size for the image

The problem is that the size of CanvasControl is not suit for image source (Image: 960*640 CanvasControl:500*400). If you want to make CanvasControl could display the full image, please set available dpi when call CanvasBitmap.LoadAsync method. For my testing 185 is suit for your scenario.

async Task CreateResourcesAsync(CanvasControl sender)
{
    cbi = await CanvasBitmap.LoadAsync(sender, "Flower1.jpg",185);

}

Update

//var dpi = DisplayInformation.GetForCurrentView().LogicalDpi;
var display = DisplayInformation.GetForCurrentView();
// calculate your monitor's dpi
var dpi = Math.Sqrt(Math.Pow(display.ScreenWidthInRawPixels, 2) + Math.Pow(display.ScreenHeightInRawPixels, 2)) / display.DiagonalSizeInInches;
// get the CanvasControl inch 
var inch = Math.Sqrt(Math.Pow(500, 2) + Math.Pow(400, 2)) / dpi;
// calculate last dpi with the image size
var lastdpi = Math.Sqrt(Math.Pow(960, 2) + Math.Pow(640, 2)) / inch;

Update 1

If could also set CanvasControl size with image size that could avoid to calculate Dpi.

Update 2

And you could also resize your image to suit for CanvasControl, Please refer the following code.

public async Task<IRandomAccessStream> ResizeImage(StorageFile file, int reqWidth, int reqHeight)
{
    var memStream = new MemoryStream();
    using (Stream stream = await file.OpenStreamForReadAsync())
    {
        stream.CopyTo(memStream);
    }
    IRandomAccessStream imageStream = memStream.AsRandomAccessStream();
    var decoder = await BitmapDecoder.CreateAsync(imageStream);
    if (decoder.PixelHeight > reqHeight || decoder.PixelWidth > reqWidth)
    {
        using (imageStream)
        {
            var resizedStream = new InMemoryRandomAccessStream();

            BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(resizedStream, decoder);
            double widthRatio = (double)reqWidth / decoder.PixelWidth;
            double heightRatio = (double)reqHeight / decoder.PixelHeight;

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

            if (reqWidth == 0)
                scaleRatio = heightRatio;

            if (reqHeight == 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();

            return resizedStream;
        }
    }
    return imageStream;
}

Usage

async Task CreateResourcesAsync(CanvasControl sender)
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Flower1.jpg")); 
    cbi = await CanvasBitmap.LoadAsync(sender, await ResizeImage(file, 500, 400));    
}

这篇关于在 UWP 中使用模糊效果绘制图像未正确设置图像大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆