none
canvas 上面截取图片 RRS feed

  • 问题

  • 您好:

          现在有个canvas,我拖动鼠标后,得到一个矩形,想得到矩形包括的canvas的部分,变成图片

          如何实现,求指教.......谢谢

    2011年3月9日 15:24

答案

  • 如果是要截取整个Canvas的话,使用 RenderTargetBitmap 就可以完成了,但是如果你要使用鼠标在canvas上画一个矩形,然后保存你所画的内容,这个就相对会复杂一些了,参考下面的链接:

    http://www.codeproject.com/KB/WPF/ImageCropper.aspx?msg=3190174

     


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 elegantluo 2011年3月11日 18:24
    2011年3月10日 3:43
    版主
  • 谢谢,肖哥~看了你的发的链接,我终于完成了,在这个过程,感谢朋友们的支持:

    我把源程序贴出来,供朋友们参考:

    <Window x:Class="TestWpf.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="300" Width="300">
      <DockPanel>
        <Canvas Background="Yellow" Width="auto" Height="auto" Name="canvas1" MouseDown="canvas1_MouseDown" MouseMove="canvas1_MouseMove" MouseUp="canvas1_MouseUp">
          <Line X1="0" X2="400" Y1="0" Y2="400" Stroke="Blue" Height="262" Width="278" StrokeThickness="5"></Line>
          <Line X1="0" X2="200" Y1="0" Y2="400" Stroke="Red" Height="262" Width="278" StrokeThickness="5"></Line>
          <Line X1="0" X2="400" Y1="0" Y2="200" Stroke="Green" Height="262" Width="278" StrokeThickness="5"></Line>    
        </Canvas> 
      </DockPanel>
    </Window>
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace TestWpf
    {
      /// <summary>
      /// Window1.xaml 的交互逻辑
      /// </summary>
      public partial class Window1 : Window
      {
        public Window1()
        {
          InitializeComponent();
        }
        Point downPoint;
        Point upPoint;
        Point currentPoint;
        bool isMouseDown = false;
        Rectangle rubberBand = null;
        string savePath = @"c:\canvas1.jpg";
        string selectPath = @"c:\select1x.jpg";
        private double zoomFactor = 1.0;
    
    
        private void canvas1_MouseDown(object sender, MouseButtonEventArgs e)
        {
          //MessageBox.Show("niaho");
          if (!this.canvas1.IsMouseCaptured)
          {
    
            isMouseDown = true;
            downPoint = new Point();
            downPoint = e.GetPosition(this.canvas1);
          }
    
        }
    
        private void canvas1_MouseMove(object sender, MouseEventArgs e)
        {
         
          if (isMouseDown == true)
          {
            
    
            if (rubberBand == null)
            {
              rubberBand = new Rectangle();
              rubberBand.Stroke = Brushes.LightCoral;
              rubberBand.StrokeDashArray = new DoubleCollection(new double[] { 4, 2 });
              canvas1.Children.Add(rubberBand);
            }
    
            currentPoint = e.GetPosition(this.canvas1);
    
            double width = Math.Abs(downPoint.X - currentPoint.X);
            double height = Math.Abs(downPoint.Y - currentPoint.Y);
            double left = Math.Min(downPoint.X, currentPoint.X);
            double top = Math.Min(downPoint.Y, currentPoint.Y);
            rubberBand.Width = width;
            rubberBand.Height = height;
            Canvas.SetLeft(rubberBand, left);
            Canvas.SetTop(rubberBand, top);
    
          }
        }
        private void canvas1_MouseUp(object sender, MouseButtonEventArgs e)
        {
    
          if (!this.canvas1.IsMouseCaptured)
          {
    
            isMouseDown = false;
            upPoint = new Point();
            upPoint = e.GetPosition(this.canvas1);
            CanvasToJpg(downPoint, upPoint);
            RectangleToJpg();
    
          }
        }
    
        private void CanvasToJpg(Point pt1, Point pt2)
        { 
          RenderTargetBitmap bmp = new RenderTargetBitmap((int)canvas1.ActualWidth, (int)canvas1.ActualHeight, 96, 96, PixelFormats.Pbgra32);
          bmp.Render(canvas1);
          string Extension = System.IO.Path.GetExtension(savePath).ToLower();
          BitmapEncoder encoder = new JpegBitmapEncoder();
          encoder.Frames.Add(BitmapFrame.Create(bmp));
          using (System.IO.Stream stm = System.IO.File.Create(savePath))
          {
            encoder.Save(stm);
          }
        }
        private void RectangleToJpg()
        {
          double rubberBandLeft = Canvas.GetLeft(rubberBand);
          double rubberBandTop = Canvas.GetTop(rubberBand);
          using (System.Drawing.Bitmap source =
              new System.Drawing.Bitmap(savePath))
          {
            
            using (System.Drawing.Bitmap target =
               new System.Drawing.Bitmap((int)rubberBand.Width,
               (int)rubberBand.Height))
            {
              System.Drawing.RectangleF recDest =
                 new System.Drawing.RectangleF
                (0.0f, 0.0f, (float)target.Width,
                (float)target.Height);
              float hd = 1.0f / (target.HorizontalResolution /
                        source.HorizontalResolution);
              float vd = 1.0f / (target.VerticalResolution /
                         source.VerticalResolution);
              float hScale = 1.0f / (float)zoomFactor;
              float vScale = 1.0f / (float)zoomFactor;
              System.Drawing.RectangleF recSrc =
                new System.Drawing.RectangleF
                ((hd * (float)rubberBandLeft) *
                hScale, (vd * (float)rubberBandTop) *
                vScale, (hd * (float)rubberBand.Width) *
                hScale, (vd * (float)rubberBand.Height) *
                vScale);
              using (System.Drawing.Graphics gfx =
                System.Drawing.Graphics.FromImage(target))
              {
                gfx.DrawImage(source, recDest, recSrc,
                  System.Drawing.GraphicsUnit.Pixel);
              }
              
              target.Save(selectPath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
          }
    
        }
    
    
      }
    }
    
    

     

    • 已标记为答案 elegantluo 2011年3月11日 18:24
    2011年3月11日 18:23

全部回复

  • 如果是要截取整个Canvas的话,使用 RenderTargetBitmap 就可以完成了,但是如果你要使用鼠标在canvas上画一个矩形,然后保存你所画的内容,这个就相对会复杂一些了,参考下面的链接:

    http://www.codeproject.com/KB/WPF/ImageCropper.aspx?msg=3190174

     


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 elegantluo 2011年3月11日 18:24
    2011年3月10日 3:43
    版主
  • 谢谢,肖哥~看了你的发的链接,我终于完成了,在这个过程,感谢朋友们的支持:

    我把源程序贴出来,供朋友们参考:

    <Window x:Class="TestWpf.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="300" Width="300">
      <DockPanel>
        <Canvas Background="Yellow" Width="auto" Height="auto" Name="canvas1" MouseDown="canvas1_MouseDown" MouseMove="canvas1_MouseMove" MouseUp="canvas1_MouseUp">
          <Line X1="0" X2="400" Y1="0" Y2="400" Stroke="Blue" Height="262" Width="278" StrokeThickness="5"></Line>
          <Line X1="0" X2="200" Y1="0" Y2="400" Stroke="Red" Height="262" Width="278" StrokeThickness="5"></Line>
          <Line X1="0" X2="400" Y1="0" Y2="200" Stroke="Green" Height="262" Width="278" StrokeThickness="5"></Line>    
        </Canvas> 
      </DockPanel>
    </Window>
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace TestWpf
    {
      /// <summary>
      /// Window1.xaml 的交互逻辑
      /// </summary>
      public partial class Window1 : Window
      {
        public Window1()
        {
          InitializeComponent();
        }
        Point downPoint;
        Point upPoint;
        Point currentPoint;
        bool isMouseDown = false;
        Rectangle rubberBand = null;
        string savePath = @"c:\canvas1.jpg";
        string selectPath = @"c:\select1x.jpg";
        private double zoomFactor = 1.0;
    
    
        private void canvas1_MouseDown(object sender, MouseButtonEventArgs e)
        {
          //MessageBox.Show("niaho");
          if (!this.canvas1.IsMouseCaptured)
          {
    
            isMouseDown = true;
            downPoint = new Point();
            downPoint = e.GetPosition(this.canvas1);
          }
    
        }
    
        private void canvas1_MouseMove(object sender, MouseEventArgs e)
        {
         
          if (isMouseDown == true)
          {
            
    
            if (rubberBand == null)
            {
              rubberBand = new Rectangle();
              rubberBand.Stroke = Brushes.LightCoral;
              rubberBand.StrokeDashArray = new DoubleCollection(new double[] { 4, 2 });
              canvas1.Children.Add(rubberBand);
            }
    
            currentPoint = e.GetPosition(this.canvas1);
    
            double width = Math.Abs(downPoint.X - currentPoint.X);
            double height = Math.Abs(downPoint.Y - currentPoint.Y);
            double left = Math.Min(downPoint.X, currentPoint.X);
            double top = Math.Min(downPoint.Y, currentPoint.Y);
            rubberBand.Width = width;
            rubberBand.Height = height;
            Canvas.SetLeft(rubberBand, left);
            Canvas.SetTop(rubberBand, top);
    
          }
        }
        private void canvas1_MouseUp(object sender, MouseButtonEventArgs e)
        {
    
          if (!this.canvas1.IsMouseCaptured)
          {
    
            isMouseDown = false;
            upPoint = new Point();
            upPoint = e.GetPosition(this.canvas1);
            CanvasToJpg(downPoint, upPoint);
            RectangleToJpg();
    
          }
        }
    
        private void CanvasToJpg(Point pt1, Point pt2)
        { 
          RenderTargetBitmap bmp = new RenderTargetBitmap((int)canvas1.ActualWidth, (int)canvas1.ActualHeight, 96, 96, PixelFormats.Pbgra32);
          bmp.Render(canvas1);
          string Extension = System.IO.Path.GetExtension(savePath).ToLower();
          BitmapEncoder encoder = new JpegBitmapEncoder();
          encoder.Frames.Add(BitmapFrame.Create(bmp));
          using (System.IO.Stream stm = System.IO.File.Create(savePath))
          {
            encoder.Save(stm);
          }
        }
        private void RectangleToJpg()
        {
          double rubberBandLeft = Canvas.GetLeft(rubberBand);
          double rubberBandTop = Canvas.GetTop(rubberBand);
          using (System.Drawing.Bitmap source =
              new System.Drawing.Bitmap(savePath))
          {
            
            using (System.Drawing.Bitmap target =
               new System.Drawing.Bitmap((int)rubberBand.Width,
               (int)rubberBand.Height))
            {
              System.Drawing.RectangleF recDest =
                 new System.Drawing.RectangleF
                (0.0f, 0.0f, (float)target.Width,
                (float)target.Height);
              float hd = 1.0f / (target.HorizontalResolution /
                        source.HorizontalResolution);
              float vd = 1.0f / (target.VerticalResolution /
                         source.VerticalResolution);
              float hScale = 1.0f / (float)zoomFactor;
              float vScale = 1.0f / (float)zoomFactor;
              System.Drawing.RectangleF recSrc =
                new System.Drawing.RectangleF
                ((hd * (float)rubberBandLeft) *
                hScale, (vd * (float)rubberBandTop) *
                vScale, (hd * (float)rubberBand.Width) *
                hScale, (vd * (float)rubberBand.Height) *
                vScale);
              using (System.Drawing.Graphics gfx =
                System.Drawing.Graphics.FromImage(target))
              {
                gfx.DrawImage(source, recDest, recSrc,
                  System.Drawing.GraphicsUnit.Pixel);
              }
              
              target.Save(selectPath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
          }
    
        }
    
    
      }
    }
    
    

     

    • 已标记为答案 elegantluo 2011年3月11日 18:24
    2011年3月11日 18:23
  • Cheers!


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年3月12日 3:21
    版主