如何绘制屏幕截图“预览”窗口?

5

我有一个Winforms应用程序,用户可以使用它来进行区域截屏。我想添加一个小预览窗口,但是不确定如何实现。到目前为止,我尝试在鼠标移动时重新创建位图,但是这样做太卡了,无法使用。因此,我想如果我使用预定义的图像(整个屏幕的截图),并根据鼠标位置将其移动到Picturebox中,以便您可以放大查看屏幕(更轻松地选择要截取的精确像素)。我不确定如何实现这一点,我对绘图也很陌生,下面是我现在的代码。

private void falseDesktop_MouseMove(object sender, MouseEventArgs e)
    {
        zoomBox.Image = showZoomBox(e.Location);
        zoomBox.Invalidate();
    }

private Image showZoomBox(Point curLocation)
        {
            int x = 0;
            int y = 0;
            if (curLocation.X - 12 <= 0)
            {
                x = curLocation.X - 12;
            }
            else
            {
                x = curLocation.X;
            }

            if (curLocation.Y - 11 <= 0)
            {
                y = curLocation.Y - 11;
            }
            else
            {
                y = curLocation.Y;
            }

            Point start = new Point(curLocation.X - 12, curLocation.Y - 11);
            Size size = new Size(24, 22);
            Rectangle rect = new Rectangle(start, size);
            Image selection = cropImage(falseDesktop.Image, rect);
            return selection;
        }

private static Image cropImage(Image img, Rectangle cropArea)
    {
        if (cropArea.Width != 0 && cropArea.Height != 0)
        {
            Bitmap bmpImage = new Bitmap(img);
            Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
            bmpImage.Dispose();
            return (Image)(bmpCrop);
        }
        return null;
    }

编辑:

这是一个模拟图,如您所请求的:

这张图片黑色的部分是一个面板,其中文本是标签,您看到的图像区域(堆栈溢出)将是图片框(称为zoomBox),放在zoomBox上方的线条将成为指南,两条线相交的位置将是鼠标的位置。希望这可以更好地帮助您理解我的问题。

alt text

另一件可能有助于解释我的问题的事情是,该窗体实际上填充了整个屏幕,带有“假桌面”。它是一个图片框,覆盖整个屏幕,截取按下“打印屏幕”时桌面的屏幕截图。所以我希望这个小的“预览窗格”基本上是放大了鼠标所在位置的位置。


你的问题听起来很有趣,但是从代码片段中很难弄清楚你的意图。我认为最好的方式是使用 MS Paint 创建一个模拟图来展示你想要的东西。(你需要上传并链接模拟图...) - Paul Sasik
@Paul:我为你添加了更多细节和一个模拟图像。 - Alex
我添加了一个完整的代码示例,可能会对你有所帮助。它是硬编码的,有点hack-ish,但可能对你有用。 - Paul Sasik
只是一个警告:这个应用听起来很像Windows Vista和7捆绑的截图工具 - Powerlord
剪切工具代码在这里:https://dev59.com/-nA75IYBdhLWcg3wv77A#3124252 - Hans Passant
2个回答

2

这可能有点卡顿,但值得一试:

这是一个单文件的WInForms应用程序,展示了“实时”缩放的工作原理。它不会绘制十字线等内容,这取决于您。

关键部分:

  • _scale
  • PictureBoxSizeMode.StretchImage

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;

static class Program {
[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
}

public class Form1 : Form {
private Bitmap _myImage = new Bitmap(@"C:\Users\Public\Pictures\Sample   Pictures\LightHouse.jpg");
private int _scale = 10; // keep this < 15

private PictureBox pboxMain;
private PictureBox pboxZoom;
private System.ComponentModel.IContainer components;

public Form1() {
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
    pboxMain.Image = _myImage;
}

private void pboxMain_MouseMove(object sender, MouseEventArgs e) {
    try {
        Rectangle rc = new Rectangle(
            new Point(e.X - _scale, e.Y - _scale),
            new Size(_scale * 2, _scale * 2));
        pboxZoom.Image = _myImage.Clone(rc, PixelFormat.DontCare);
    }
    catch (OutOfMemoryException  ex) {/* ignore... */}
}

protected override void Dispose(bool disposing) {
    if (disposing && (components != null)) {
        components.Dispose();
    }
    base.Dispose(disposing);
}

private void InitializeComponent() {
    this.pboxMain = new PictureBox();
    this.pboxZoom = new PictureBox();
    ((System.ComponentModel.ISupportInitialize)(this.pboxMain)).BeginInit();
    ((System.ComponentModel.ISupportInitialize)(this.pboxZoom)).BeginInit();
    this.SuspendLayout();

    this.pboxMain.Dock = DockStyle.Fill;
    this.pboxMain.Location = new System.Drawing.Point(0, 0);
    this.pboxMain.Name = "pboxMain";
    this.pboxMain.Size = new System.Drawing.Size(767, 435);
    this.pboxMain.TabIndex = 0;
    this.pboxMain.TabStop = false;
    this.pboxMain.MouseMove += new MouseEventHandler(this.pboxMain_MouseMove);

    this.pboxZoom.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))),
  ((int)(((byte)(255)))), ((int)(((byte)(192)))));
    this.pboxZoom.BorderStyle = BorderStyle.FixedSingle;
    this.pboxZoom.Location = new System.Drawing.Point(12, 12);
    this.pboxZoom.Name = "pboxZoom";
    this.pboxZoom.Size = new System.Drawing.Size(106, 83);
    this.pboxZoom.SizeMode = PictureBoxSizeMode.StretchImage;
    this.pboxZoom.TabIndex = 1;
    this.pboxZoom.TabStop = false;

    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(767, 435);
    this.Controls.Add(this.pboxZoom);
    this.Controls.Add(this.pboxMain);
    this.Name = "Form1";
    this.Text = "Form1";
    this.Load += new System.EventHandler(this.Form1_Load);
    ((System.ComponentModel.ISupportInitialize)(this.pboxMain)).EndInit();
    ((System.ComponentModel.ISupportInitialize)(this.pboxZoom)).EndInit();
    this.ResumeLayout(false);
}
}

0

我已经将其编程,并且它确实非常好用 :) - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接