如何计算 DropShadowEffect 的大小?
How to calculate the size of a DropShadowEffect?
我正在尝试获取图像并对其应用投影并另存为图像。
到目前为止,不使用第三方解决方案的唯一方法是在 DrawingVisual
:
中使用 DropShadowEffect
var drawingVisual = new DrawingVisual();
drawingVisual.Effect = new DropShadowEffect
{
Color = Color.FromArgb(255, 0, 0, 0),
BlurRadius = 5,
Opacity = 1,
Direction = 45,
ShadowDepth = 6
};
using (var drawingContext = drawingVisual.RenderOpen())
{
var left = 0; //??
var top = 0; //??
var totalWidth = left + image.Width; //??
var totalHeight = top + image.Height; //??
//Background.
drawingContext.DrawRectangle(new SolidColorBrush(Colors.White), null, new Rect(0,0, totalWidth, totalHeight));
//Image.
drawingContext.DrawImage(image, new Rect(left, top, image.Width, image.Height));
}
var frameHeight = image.PixelHeight; //??
var frameWidth = image.PixelWidth; //??
//Converts the Visual (DrawingVisual) into a BitmapSource.
var bmp = new RenderTargetBitmap(frameWidth, frameHeight, imageDpi, imageDpi, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
//Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder.
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
//Saves the image into a file using the encoder.
using (Stream stream = File.Create(frame.Path))
encoder.Save(stream);
我不知道为给定 DropShadowEffect
.
检测所有边的精确像素偏移所需的数学知识
有没有内置的方法来测量它,还是我应该手动测量?
如何手动完成?
如果您查看 .NET source code for the DropShadowEffect,可以使用内部方法 GetRenderBounds
来制定您正在寻找的答案。
虽然您无法使用 GetRenderBounds,但代码非常简单,您可以创建自己的辅助方法。
参考代码如下:
/// <summary>
/// Takes in content bounds, and returns the bounds of the rendered
/// output of that content after the Effect is applied.
/// </summary>
internal override Rect GetRenderBounds(Rect contentBounds)
{
Point topLeft = new Point();
Point bottomRight = new Point();
double radius = BlurRadius;
topLeft.X = contentBounds.TopLeft.X - radius;
topLeft.Y = contentBounds.TopLeft.Y - radius;
bottomRight.X = contentBounds.BottomRight.X + radius;
bottomRight.Y = contentBounds.BottomRight.Y + radius;
double depth = ShadowDepth;
double direction = Math.PI/180 * Direction;
double offsetX = depth * Math.Cos(direction);
double offsetY = depth * Math.Sin(direction);
// If the shadow is horizontally aligned or to the right of the original element...
if (offsetX >= 0.0f)
{
bottomRight.X += offsetX;
}
// If the shadow is to the left of the original element...
else
{
topLeft.X += offsetX;
}
// If the shadow is above the original element...
if (offsetY >= 0.0f)
{
topLeft.Y -= offsetY;
}
// If the shadow is below the original element...
else
{
bottomRight.Y -= offsetY;
}
return new Rect(topLeft, bottomRight);
}
希望对您有所帮助。
问题作者更新
这是我使用的实际代码:
//Draws image with shadow.
using (var drawingContext = drawingVisual.RenderOpen())
{
//Measure drop shadow space.
var point1 = new Point(0 - model.BlurRadius / 2d, 0 - model.BlurRadius / 2d);
var point2 = new Point(image.PixelWidth + model.BlurRadius / 2d, image.PixelHeight + model.BlurRadius / 2d);
var num1 = Math.PI / 180.0 * model.Direction;
var num2 = model.Depth * Math.Cos(num1);
var num3 = model.Depth * Math.Sin(num1);
if (num2 >= 0.0)
point2.X += num2; //If the shadow is horizontally aligned or to the right of the original element...
else
point1.X += num2; //If the shadow is to the left of the original element...
if (num3 >= 0.0)
point1.Y -= num3; //If the shadow is above the original element...
else
point2.Y -= num3; //If the shadow is below the original element...
var left = Math.Abs(point1.X);
var top = Math.Abs(point1.Y);
var totalWidth = left + point2.X;
var totalHeight = top + point2.Y;
//Image.
drawingContext.DrawImage(image, new Rect((int)left, (int)top, image.PixelWidth, image.PixelHeight));
frameHeight = (int)totalHeight;
frameWidth = (int)totalWidth;
}
我正在尝试获取图像并对其应用投影并另存为图像。
到目前为止,不使用第三方解决方案的唯一方法是在 DrawingVisual
:
DropShadowEffect
var drawingVisual = new DrawingVisual();
drawingVisual.Effect = new DropShadowEffect
{
Color = Color.FromArgb(255, 0, 0, 0),
BlurRadius = 5,
Opacity = 1,
Direction = 45,
ShadowDepth = 6
};
using (var drawingContext = drawingVisual.RenderOpen())
{
var left = 0; //??
var top = 0; //??
var totalWidth = left + image.Width; //??
var totalHeight = top + image.Height; //??
//Background.
drawingContext.DrawRectangle(new SolidColorBrush(Colors.White), null, new Rect(0,0, totalWidth, totalHeight));
//Image.
drawingContext.DrawImage(image, new Rect(left, top, image.Width, image.Height));
}
var frameHeight = image.PixelHeight; //??
var frameWidth = image.PixelWidth; //??
//Converts the Visual (DrawingVisual) into a BitmapSource.
var bmp = new RenderTargetBitmap(frameWidth, frameHeight, imageDpi, imageDpi, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
//Creates a PngBitmapEncoder and adds the BitmapSource to the frames of the encoder.
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
//Saves the image into a file using the encoder.
using (Stream stream = File.Create(frame.Path))
encoder.Save(stream);
我不知道为给定 DropShadowEffect
.
有没有内置的方法来测量它,还是我应该手动测量? 如何手动完成?
如果您查看 .NET source code for the DropShadowEffect,可以使用内部方法 GetRenderBounds
来制定您正在寻找的答案。
虽然您无法使用 GetRenderBounds,但代码非常简单,您可以创建自己的辅助方法。
参考代码如下:
/// <summary>
/// Takes in content bounds, and returns the bounds of the rendered
/// output of that content after the Effect is applied.
/// </summary>
internal override Rect GetRenderBounds(Rect contentBounds)
{
Point topLeft = new Point();
Point bottomRight = new Point();
double radius = BlurRadius;
topLeft.X = contentBounds.TopLeft.X - radius;
topLeft.Y = contentBounds.TopLeft.Y - radius;
bottomRight.X = contentBounds.BottomRight.X + radius;
bottomRight.Y = contentBounds.BottomRight.Y + radius;
double depth = ShadowDepth;
double direction = Math.PI/180 * Direction;
double offsetX = depth * Math.Cos(direction);
double offsetY = depth * Math.Sin(direction);
// If the shadow is horizontally aligned or to the right of the original element...
if (offsetX >= 0.0f)
{
bottomRight.X += offsetX;
}
// If the shadow is to the left of the original element...
else
{
topLeft.X += offsetX;
}
// If the shadow is above the original element...
if (offsetY >= 0.0f)
{
topLeft.Y -= offsetY;
}
// If the shadow is below the original element...
else
{
bottomRight.Y -= offsetY;
}
return new Rect(topLeft, bottomRight);
}
希望对您有所帮助。
问题作者更新
这是我使用的实际代码:
//Draws image with shadow.
using (var drawingContext = drawingVisual.RenderOpen())
{
//Measure drop shadow space.
var point1 = new Point(0 - model.BlurRadius / 2d, 0 - model.BlurRadius / 2d);
var point2 = new Point(image.PixelWidth + model.BlurRadius / 2d, image.PixelHeight + model.BlurRadius / 2d);
var num1 = Math.PI / 180.0 * model.Direction;
var num2 = model.Depth * Math.Cos(num1);
var num3 = model.Depth * Math.Sin(num1);
if (num2 >= 0.0)
point2.X += num2; //If the shadow is horizontally aligned or to the right of the original element...
else
point1.X += num2; //If the shadow is to the left of the original element...
if (num3 >= 0.0)
point1.Y -= num3; //If the shadow is above the original element...
else
point2.Y -= num3; //If the shadow is below the original element...
var left = Math.Abs(point1.X);
var top = Math.Abs(point1.Y);
var totalWidth = left + point2.X;
var totalHeight = top + point2.Y;
//Image.
drawingContext.DrawImage(image, new Rect((int)left, (int)top, image.PixelWidth, image.PixelHeight));
frameHeight = (int)totalHeight;
frameWidth = (int)totalWidth;
}