我是自定义在屏幕上绘制两个放大图像,一个是彼此相邻的。每个人占据屏幕的一半。
我以前通过覆盖OnPaint()来完成.net 3.5(我认为):
//using System.Drawing
/// <summary>
/// Custom drawing
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit);
}
DrawImage方法的描述:“在指定位置以指定大小绘制指定Image的指定部分。” (MSDN)
我正在尝试使用.net 4.5实现相同的目标。我重写OnRender并使用DrawingContext对象来执行我的绘图。基本上这是我的循环:
//using System.Windows.Media;
/// <summary>
/// Overide the OnRender to have access to a lower level of drawing.
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf);
drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf);
}
如果我想显示拉伸的图片,它可以正常工作。我想要的是显示(在Window_LeftHalf和Window_RightHalf中)图片的一部分(如放大)。基本上是graphics.DrawImage(见上图),但使用DrawingContext对象。
我试过看MSDN,但我无法提出任何有趣的内容。也许创建一个稍后由DrawingContext使用的缓冲区?我几乎可以肯定需要一个保存放大图像的中间对象。有什么想法吗?
更新:我使用鼠标浏览图像,因此 的性能非常重要。例如:
/// <summary>
/// Handles the mouse move events.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MouseMoveEventHandler(RoutedEventArgs e)
{
// The size of the crop is always the same
// but the portion of the picture different.
crop.X += mouseDelta.X;
crop.Y += mouseDelta.Y;
}
答案 0 :(得分:3)
看一下CroppedBitmap
课程。就像您以前使用e.Graphics.DrawImage()
一样,CroppedBitmap
允许您仅指定您感兴趣的图像部分。
以下是一个例子:
protected override void OnRender(System.Windows.Media.DrawingContext dc)
{
int halfWidth = (int)this.Width / 2;
int height = (int)this.Height;
BitmapImage leftImage = new BitmapImage(new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"));
BitmapImage rightImage = new BitmapImage(new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));
CroppedBitmap leftImageCropped = new CroppedBitmap(leftImage, new Int32Rect(0, 0, halfWidth, height));
CroppedBitmap rightImageCropped = new CroppedBitmap(rightImage, new Int32Rect(0, 0, halfWidth, height));
dc.DrawImage(leftImageCropped, new System.Windows.Rect(0, 0, leftImageCropped.Width, height));
dc.DrawImage(rightImageCropped, new System.Windows.Rect(halfWidth, 0, halfWidth, height));
}
答案 1 :(得分:0)
编辑2 :
ImageBrush.Viewbox
。 Viewbox是Rect
,其尺寸为[0.0 ... 1.0],可让您控制曾经是SourceRect的内容。我对此进行了测试,效果非常出色。我做了什么:
在我的窗口中:
protected ImageBrush imgBrush = new ImageBrush(new ImageSource(new Uri("image.png")));
protected Rect vBox = new Rect(0, 0, 1, 1);
protected Point lastPosition = new Point(0, 0);
我的容器是一个名为 tgtRect 的WPF矩形,其Rect.Fill
是 imgBrush 。缩放和滚动方法如下:
protected void tgtRect_MouseWheel(object sender, MouseWheelEventArgs e)
{
// Zoom in when Delta is positive, Zoom out when negative
double exp = -e.Delta / Math.Abs(e.Delta);
double val = Math.Pow(1.1, exp);
vBox.Scale(val, val);
imgBrush.Viewbox = vBox;
}
void tgtRect_MouseMove(object sender, MouseEventArgs e)
{
Point thisPosition = e.GetPosition(tgtRect);
if (e.RightButton == MouseButtonState.Pressed)
{
double w = tgtRect.ActualWidth;
double h = tgtRect.ActualHeight;
Vector offset = lastPosition - thisPosition;
offset.X /= w;
offset.Y /= h;
vBox.Offset(offset);
imgBrush.Viewbox = vBox;
}
lastPosition = thisPosition;
}
对于您的实施:
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawRectangle(imgBrush, null, DesRect);
}
您可能需要为要绘制的每个矩形维护一个单独的imgBrush。我在WPF窗口中尝试了上面的代码(不是OnRender覆盖),只有一个Rectangle.Fill
是ImageBrush
的矩形,性能非常好。如果你有任何麻烦,我想我们可以解决它,但我认为ImageBrush最终将成为正确的实现。这是一个非常有趣的项目!谢谢你的提问。
END EDIT 2
您需要将Rect
个对象“Window_LeftHalf”和“Window_RightHalf”定义为您希望渲染图像的实际大小。例如,如果缩放率为200%,则Rect.Width
和Rect.Height
属性的大小必须是原始ImageSource的2倍。
修改强>:
旧方法是:
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit);
}
使用'BitmapImage.SourceRect`:
protected override void OnRender(DrawingContext drawingContext)
{
BitmapImage_Left.SourceRect = SrcRectangleLeft;
drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf);
BitmapImage_Right.SourceRect = SrcRectangleRight;
drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf);
}
您的鼠标功能可以更改SourceRect。例如:
private static void MouseMoveEventHandler(RoutedEventArgs e)
{
// The size of the crop is always the same
// but the portion of the picture different.
SrcRectangleLeft = new Int32Rect(SrcRectangleLeft.X + mouseDelta.X,
SrcRectangleLeft.Y + mouseDelta.Y,
SrcRectangleLeft.Width, SrcRectangleLeft.Height);
}
不确定性能如何,但应该比每次更新时将位图的部分映射到新对象更好。
希望这有帮助。