Windows10万能App如何制作毛玻璃效果?
How to make frosted glass effect in Windows 10 Universal App?
那么,如何使用 C# 制作这样的效果 & XAML?
您应该查看 Win2D 类 并在其中找到 Canvas 效果 - GaussianBlurEffect 可能会有所帮助。这是参考:
http://microsoft.github.io/Win2D/html/N_Microsoft_Graphics_Canvas_Effects.htm
对于 GaussianBlurEffect:
http://microsoft.github.io/Win2D/html/T_Microsoft_Graphics_Canvas_Effects_GaussianBlurEffect.htm
包括一些 C# 代码示例。
补充:如果你想知道如何使用 win2D,我刚刚找到了一个方便的教程(我现在正在关注 :))http://blogs.msdn.com/b/uk_faculty_connection/archive/2014/09/05/win2d.aspx
自从 iOS 7 引入了磨砂玻璃以来,我一直在尝试创建类似的东西。现在感谢 Win2D,在 WinRT 中创建类似的效果要简单得多。
首先,您需要从 NuGet 获取 Win2D.uwp 包。
想法是根据图像源创建一个 GaussianBlurEffect
并将其放在另一个 白色 彩色蒙版之上以模仿磨砂玻璃外观。
要准备好 GaussianBlurEffect
,您需要从 Win2D 库中创建一个 xaml 控件 CanvasControl
。所以 UI 结构是这样的 -
<Grid x:Name="ImagePanel2" Width="356" Height="200" Margin="0,0,0,40" VerticalAlignment="Bottom">
<Image x:Name="Image2" Source="Assets/Food.jpg" Stretch="UniformToFill" />
<Grid x:Name="Overlay" ManipulationMode="TranslateX" ManipulationStarted="Overlay_ManipulationStarted" ManipulationDelta="Overlay_ManipulationDelta" ManipulationCompleted="Overlay_ManipulationCompleted" RenderTransformOrigin="0.5,0.5">
<Grid.Clip>
<RectangleGeometry x:Name="Clip" Rect="0, 0, 356, 200" />
</Grid.Clip>
<Rectangle x:Name="WhiteMask" Fill="White" />
<Xaml:CanvasControl x:Name="Canvas" CreateResources="Canvas_CreateResources" Draw="Canvas_Draw" />
</Grid>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Frosted Glass" VerticalAlignment="Top" Foreground="#FF595959" Margin="12,12,0,0" FontWeight="Light" FontSize="26.667" FontStyle="Italic" TextLineBounds="Tight" />
</Grid>
请注意,我为 Overlay
元素创建了一个 Clip
,因为我需要减少 Rect
的第三个参数(即 宽度) 当我将它向左平移以产生 Overlay
随我的手指滑动的错觉时。
后面的代码非常简单 -
void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
{
args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
}
async Task CreateResourcesAsync(CanvasControl sender)
{
// give it a little bit delay to ensure the image is load, ideally you want to Image.ImageOpened event instead
await Task.Delay(200);
using (var stream = new InMemoryRandomAccessStream())
{
// get the stream from the background image
var target = new RenderTargetBitmap();
await target.RenderAsync(this.Image2);
var pixelBuffer = await target.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)target.PixelWidth, (uint)target.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
// load the stream into our bitmap
_bitmap = await CanvasBitmap.LoadAsync(sender, stream);
}
}
void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
using (var session = args.DrawingSession)
{
var blur = new GaussianBlurEffect
{
BlurAmount = 50.0f, // increase this to make it more blurry or vise versa.
//Optimization = EffectOptimization.Balanced, // default value
//BorderMode = EffectBorderMode.Soft // default value
Source = _bitmap
};
session.DrawImage(blur, new Rect(0, 0, sender.ActualWidth, sender.ActualHeight),
new Rect(0, 0, _bitmap.SizeInPixels.Width, _bitmap.SizeInPixels.Height), 0.9f);
}
}
void Overlay_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
// reset the inital with of the Rect
_x = (float)this.ImagePanel2.ActualWidth;
}
void Overlay_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// get the movement on X axis
_x += (float)e.Delta.Translation.X;
// keep the pan within the bountry
if (_x > this.ImagePanel2.ActualWidth || _x < 0) return;
// we clip the overlay to reveal the actual image underneath
this.Clip.Rect = new Rect(0, 0, _x, this.ImagePanel2.ActualHeight);
}
void Overlay_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
// reset the clip to show the full overlay
this.Clip.Rect = new Rect(0, 0, this.ImagePanel2.ActualWidth, this.ImagePanel2.ActualHeight);
}
您可以进一步调整 BlurAmount
属性 以及不透明度数字 (0.9f
) 以获得您想要的确切效果。
另请注意,将来可能会有另一种(更好?)方法来执行此操作。如果 new Composition API 在未来的版本中支持 GaussianBlurEffect
,我会更新答案。
您可以从此 GitHub repo 中找到当前工作示例。我在这里附上了一张图片来展示它的样子。 :)
那么,如何使用 C# 制作这样的效果 & XAML?
您应该查看 Win2D 类 并在其中找到 Canvas 效果 - GaussianBlurEffect 可能会有所帮助。这是参考: http://microsoft.github.io/Win2D/html/N_Microsoft_Graphics_Canvas_Effects.htm 对于 GaussianBlurEffect: http://microsoft.github.io/Win2D/html/T_Microsoft_Graphics_Canvas_Effects_GaussianBlurEffect.htm 包括一些 C# 代码示例。
补充:如果你想知道如何使用 win2D,我刚刚找到了一个方便的教程(我现在正在关注 :))http://blogs.msdn.com/b/uk_faculty_connection/archive/2014/09/05/win2d.aspx
自从 iOS 7 引入了磨砂玻璃以来,我一直在尝试创建类似的东西。现在感谢 Win2D,在 WinRT 中创建类似的效果要简单得多。
首先,您需要从 NuGet 获取 Win2D.uwp 包。
想法是根据图像源创建一个 GaussianBlurEffect
并将其放在另一个 白色 彩色蒙版之上以模仿磨砂玻璃外观。
要准备好 GaussianBlurEffect
,您需要从 Win2D 库中创建一个 xaml 控件 CanvasControl
。所以 UI 结构是这样的 -
<Grid x:Name="ImagePanel2" Width="356" Height="200" Margin="0,0,0,40" VerticalAlignment="Bottom">
<Image x:Name="Image2" Source="Assets/Food.jpg" Stretch="UniformToFill" />
<Grid x:Name="Overlay" ManipulationMode="TranslateX" ManipulationStarted="Overlay_ManipulationStarted" ManipulationDelta="Overlay_ManipulationDelta" ManipulationCompleted="Overlay_ManipulationCompleted" RenderTransformOrigin="0.5,0.5">
<Grid.Clip>
<RectangleGeometry x:Name="Clip" Rect="0, 0, 356, 200" />
</Grid.Clip>
<Rectangle x:Name="WhiteMask" Fill="White" />
<Xaml:CanvasControl x:Name="Canvas" CreateResources="Canvas_CreateResources" Draw="Canvas_Draw" />
</Grid>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Frosted Glass" VerticalAlignment="Top" Foreground="#FF595959" Margin="12,12,0,0" FontWeight="Light" FontSize="26.667" FontStyle="Italic" TextLineBounds="Tight" />
</Grid>
请注意,我为 Overlay
元素创建了一个 Clip
,因为我需要减少 Rect
的第三个参数(即 宽度) 当我将它向左平移以产生 Overlay
随我的手指滑动的错觉时。
后面的代码非常简单 -
void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
{
args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
}
async Task CreateResourcesAsync(CanvasControl sender)
{
// give it a little bit delay to ensure the image is load, ideally you want to Image.ImageOpened event instead
await Task.Delay(200);
using (var stream = new InMemoryRandomAccessStream())
{
// get the stream from the background image
var target = new RenderTargetBitmap();
await target.RenderAsync(this.Image2);
var pixelBuffer = await target.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)target.PixelWidth, (uint)target.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
// load the stream into our bitmap
_bitmap = await CanvasBitmap.LoadAsync(sender, stream);
}
}
void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
using (var session = args.DrawingSession)
{
var blur = new GaussianBlurEffect
{
BlurAmount = 50.0f, // increase this to make it more blurry or vise versa.
//Optimization = EffectOptimization.Balanced, // default value
//BorderMode = EffectBorderMode.Soft // default value
Source = _bitmap
};
session.DrawImage(blur, new Rect(0, 0, sender.ActualWidth, sender.ActualHeight),
new Rect(0, 0, _bitmap.SizeInPixels.Width, _bitmap.SizeInPixels.Height), 0.9f);
}
}
void Overlay_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
// reset the inital with of the Rect
_x = (float)this.ImagePanel2.ActualWidth;
}
void Overlay_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// get the movement on X axis
_x += (float)e.Delta.Translation.X;
// keep the pan within the bountry
if (_x > this.ImagePanel2.ActualWidth || _x < 0) return;
// we clip the overlay to reveal the actual image underneath
this.Clip.Rect = new Rect(0, 0, _x, this.ImagePanel2.ActualHeight);
}
void Overlay_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
// reset the clip to show the full overlay
this.Clip.Rect = new Rect(0, 0, this.ImagePanel2.ActualWidth, this.ImagePanel2.ActualHeight);
}
您可以进一步调整 BlurAmount
属性 以及不透明度数字 (0.9f
) 以获得您想要的确切效果。
另请注意,将来可能会有另一种(更好?)方法来执行此操作。如果 new Composition API 在未来的版本中支持 GaussianBlurEffect
,我会更新答案。
您可以从此 GitHub repo 中找到当前工作示例。我在这里附上了一张图片来展示它的样子。 :)