问题
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.
回答1:
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));
}
来源:https://stackoverflow.com/questions/57572464/drawing-image-using-blur-effects-in-uwp-is-not-properly-set-size-for-the-image