如何在列表框中选择不同的项目时,它会显示该项目的裁剪图像?

时间:2014-08-24 21:17:13

标签: c# .net winforms

列表框选择的索引事件:

private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
        {

            WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
            selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
            this.pictureBoxSnap.Image = snap.Image;
            for (int i = 0; i < rectangles.Length; i++)
            {
                if (rectangles[i] != RectClone)
                {
                    ClearGraphics = false;
                }
                else
                {
                    ClearGraphics = true;
                }
            }
            if (rectangles[listBoxSnap.SelectedIndex].Width == 0 && rectangles[listBoxSnap.SelectedIndex].Height == 0)
            {
                Reset.Enabled = false;
                ConfirmRectangle.Enabled = false;
                cm.MenuItems[0].Enabled = false;
                cm.MenuItems[1].Enabled = false;
                cm.MenuItems[2].Enabled = false;
            }
            if (rectangles[listBoxSnap.SelectedIndex].Width > 5 && rectangles[listBoxSnap.SelectedIndex].Height > 5)
            {
                Reset.Enabled = true;
                if (IsRectangleConfirmed == true)
                {
                    ConfirmRectangle.Enabled = false;
                    ClearGraphics = true;
                    cropRect = true;
                }
                else
                {
                    ConfirmRectangle.Enabled = true;
                }
                cm.MenuItems[0].Enabled = true;
                cm.MenuItems[1].Enabled = true;
                cm.MenuItems[2].Enabled = true;
            }

        }

pictureBox的paint事件:

private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
    {            
        if (pictureBoxSnap.Image != null)
        {
            {
                if (ClearGraphics == false)
                {                       
                        if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
                        {
                            e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
                        }                       
                }
                if (cropRect == true)
                {
                    if (recttest.Width > 5 && recttest.Height > 5)
                    {
                        pnt = PointToScreen(pictureBoxSnap.Location);
                        e.Graphics.Clear(Color.White);
                        e.Graphics.CopyFromScreen(pnt.X + rect.X, pnt.Y + rect.Y, rect.X, rect.Y, new Size(rect.Width, rect.Height));
                    }
                }
            }
        }           
    }

问题出在这一部分:

pnt = PointToScreen(pictureBoxSnap.Location);
e.Graphics.Clear(Color.White);
e.Graphics.CopyFromScreen(pnt.X + rect.X, pnt.Y + rect.Y, rect.X, rect.Y, new Size(rect.Width, rect.Height));

此部分绘制裁剪的矩形,但是当我在listBox中选择另一个项目然后再次使用裁剪的矩形返回此项目时,它再次绘制它并且我希望它只是为了记住它并再次显示它根据所选项目。

这部分:

if (IsRectangleConfirmed == true)
                {
                    ConfirmRectangle.Enabled = false;
                    ClearGraphics = true;
                    cropRect = true;
                }

IF:if(IsRectangleConfirmed == true)表示我现在点击了一个按钮和为此项目创建的裁剪矩形。 问题是当我每次回到这个项目时,裁剪的矩形再次被绘制,我希望它只是显示它会记住这个选定项目(索引)的裁剪矩形。

我想做的是一些事情:

  1. 当我在pictureBox上绘制矩形并在listBox中的项目之间移动时,它将记住那些已绘制矩形的项目。这部分正在运作。

  2. 当我点击按钮ConfirmRectangle_Click时,它会从我绘制的矩形中制作一个裁剪的矩形,我希望当我在listBox中的项目之间移动时,它会记住那些带有裁剪图像的项目。

  3. 此行获取最小化的Windows屏幕截图:

    this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray());

  4. 我将它们添加到listBox中,当在项目之间移动时,我会在pictureBox中看到每个项目的屏幕截图。 我现在想要对具有裁剪图像的项目执行仅截取裁剪图像部分的屏幕截图。 如果没有裁剪的图像,请从整个图像中定期截取屏幕截图。

    1. 此方法GetAllWindows在listBox中显示窗口的文本,但我想在listBox中显示的项目只是它的名称。
    2. 这是我的zip文件项目名称为CaptureZip

      CaptureZip

      这是我在winrar名称Capture中的项目:

      Capture

2 个答案:

答案 0 :(得分:1)

根据您之前的帖子,您尝试通过鼠标拖动裁剪图像。现在,您希望在选择另一个项目后再次选择该项目时将其恢复。在这种情况下,裁剪图像后,您没有将裁剪后的图像设置回SelectedItem,因此当您再次选择该项目时,它将显示裁剪的图像而非原始图像。

Image img = CropImage();
((WindowSnap)listBox.SelectedItem).Image = img;

或者您可以在WindowSnap类中创建另一个属性。

即。 public image CroppedImage {get; set;}

因此,当您选择项目时,应检查是否已裁剪项目。如果是,则可以显示裁剪的图像而不是原始图像。

WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
///Here you can draw image at your desire position as you have done using e.DrawImage 
///in pictureBoxSnap_Paint event instead of assigning pictureBoxSnap.Image property
this.pictureBoxSnap.Image = snap.CroppedImage

答案 1 :(得分:1)

pictureBoxSnap SizeMode设为normal

private bool[] isCropped;
private Image img;
private Image imgClone;

public Form1()
    {
        InitializeComponent();

        img = new Bitmap(pictureBoxSnap.Width, pictureBoxSnap.Height);
        imgClone = new Bitmap(pictureBoxSnap.Width, pictureBoxSnap.Height);
        Graphics g;
        using (g = Graphics.FromImage(img))
        {
            g.Clear(Color.White);
        }

        pictureBoxSnap.Image = img;
        ...
        ...
        rectangles = new Rectangle[listBoxSnap.Items.Count];
        isCropped = new bool[listBoxSnap.Items.Count];
        ...
    }

private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
    {
        drawpicbox(this.listBoxSnap.SelectedIndex);
    }

private void drawpicbox(int index)
    {
        Graphics g, g1;
        Size sz;
        WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
        Bitmap testBmp;

        using (g = Graphics.FromImage(img))
        {
            g.Clear(Color.White);
            sz = calculateSizeAndPosition(snap.Image.Size);

            if (isCropped[index] == true)
            {
                ConfirmRectangle.Enabled = false;

                using (testBmp = new Bitmap (img.Width , img.Height )){
                    using (g1 = Graphics.FromImage(testBmp))
                    {
                        g1.Clear(Color.White);
                        g1.DrawImage(snap.Image, (int)((pictureBoxSnap.Width - sz.Width) / 2.0), (int)((pictureBoxSnap.Height - sz.Height) / 2.0), sz.Width, sz.Height);
                    }
                    g.DrawImage(testBmp, rectangles[index], rectangles[index], GraphicsUnit.Pixel);
                    g.DrawRectangle(Pens.Firebrick, rectangles[index]);
                }
            }
            else if (rectangles[index].Width != 0)
            {
                ConfirmRectangle.Enabled = true;
                g.DrawImage(snap.Image, (int)((pictureBoxSnap.Width - sz.Width) / 2.0), (int)((pictureBoxSnap.Height - sz.Height) / 2.0), sz.Width, sz.Height);
                g.DrawRectangle(Pens.Firebrick, rectangles[index]);
            }
            else
            {
                ConfirmRectangle.Enabled = false;
                g.DrawImage(snap.Image, (int)((pictureBoxSnap.Width - sz.Width) / 2.0), (int)((pictureBoxSnap.Height - sz.Height) / 2.0), sz.Width, sz.Height);
            }

        }

        pictureBoxSnap.Invalidate();
    }

private Size calculateSizeAndPosition(Size snapSize)
    {
        int wdth, hgt;
        Single  flt;

        wdth = snapSize.Width;
        hgt = snapSize.Height;

        flt = (Single)wdth / (Single)hgt;

        if (wdth <= pictureBoxSnap.Width && hgt <= pictureBoxSnap.Height)
        {

            //return new Size(wdth, hgt);
        }
        else{
            if(wdth >= hgt){
                while (true)
                {
                    wdth--;
                    hgt = (int)(wdth / flt);

                    if (wdth <= pictureBoxSnap.Width && hgt <= pictureBoxSnap.Height)
                    {
                        break;
                    }

                }
            }
            else{
                while (true)
                {
                    hgt--;
                    wdth = (int)((Single)hgt * flt);

                    if (wdth <= pictureBoxSnap.Width && hgt <= pictureBoxSnap.Height)
                    {
                        break;
                    }

                }
            }
        }

        return new Size(wdth, hgt);
    }

private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
    {

        if (isCropped[listBoxSnap.SelectedIndex] == false && e.Button == MouseButtons.Left && e.Location != RectStartPoint)
        {
            DrawRectangle(e.Location);
        }
    }

private void DrawRectangle(Point pnt)
    {
        Graphics g = Graphics.FromImage(img);


        //g.DrawRectangle(Pens.Firebrick, 50, 50, 300, 200);

        g.DrawImage(imgClone, 0, 0);

        if (pnt.X == RectStartPoint.X || pnt.Y == RectStartPoint.Y)
        {
            g.DrawLine(Pens.Firebrick, RectStartPoint.X, RectStartPoint.Y, pnt.X, pnt.Y);
        }
        else if (pnt.X > RectStartPoint.X && pnt.Y > RectStartPoint.Y) //Right-Down
        {
            rect.X = RectStartPoint.X; rect.Y = RectStartPoint.Y; rect.Width = pnt.X - RectStartPoint.X; rect.Height = pnt.Y - RectStartPoint.Y;
            g.DrawRectangle(Pens.Firebrick, rect);
        }
        else if (pnt.X > RectStartPoint.X && pnt.Y < RectStartPoint.Y) //Right-Up
        {
            rect.X = RectStartPoint.X; rect.Y = pnt.Y; rect.Width = pnt.X - RectStartPoint.X; rect.Height = RectStartPoint.Y - pnt.Y;
            g.DrawRectangle(Pens.Firebrick, rect);
        }
        else if (pnt.X < RectStartPoint.X && pnt.Y > RectStartPoint.Y) //Left-Down
        {
            rect.X = pnt.X; rect.Y = RectStartPoint.Y; rect.Width = RectStartPoint.X - pnt.X; rect.Height = pnt.Y - RectStartPoint.Y;
            g.DrawRectangle(Pens.Firebrick, rect);
        }
        else //Left-Up
        {
            rect.X = pnt.X; rect.Y = pnt.Y; rect.Width = RectStartPoint.X - pnt.X; rect.Height = RectStartPoint.Y - pnt.Y;
            g.DrawRectangle(Pens.Firebrick, rect);
        }

        g.Dispose();

        pictureBoxSnap.Invalidate();
    }

private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
    {
        Graphics g;
        Size sz;

        if (isCropped[listBoxSnap.SelectedIndex] == false && e.Button == MouseButtons.Left)
        {
            WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;

            RectStartPoint = e.Location;

            sz = calculateSizeAndPosition(snap.Image.Size);

            using (g = Graphics.FromImage(imgClone))
            {
                g.Clear(Color.White);
                g.DrawImage(snap.Image, (int)((pictureBoxSnap.Width - sz.Width) / 2.0), (int)((pictureBoxSnap.Height - sz.Height) / 2.0), sz.Width, sz.Height);
            }
        }
    }

private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
    {
        if (isCropped[listBoxSnap.SelectedIndex] == false && e.Button == MouseButtons.Left && e.Location.X != RectStartPoint.X && e.Location.Y != RectStartPoint.Y)
        {
            ConfirmRectangle.Enabled = true;
            rectangles[listBoxSnap.SelectedIndex] = rect;
            //drawpicbox(this.listBoxSnap.SelectedIndex);
        }
    }

private void ConfirmRectangle_Click(object sender, EventArgs e)
    {
        isCropped[this.listBoxSnap.SelectedIndex] = true;
        drawpicbox(this.listBoxSnap.SelectedIndex);
    }

private void Reset_Click(object sender, EventArgs e)
    {
        isCropped[this.listBoxSnap.SelectedIndex] = false;
        rectangles[this.listBoxSnap.SelectedIndex] = new Rectangle(0, 0, 0, 0);

        drawpicbox(this.listBoxSnap.SelectedIndex);
    }

private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
    { 
        //Nothing
    }

private void RefreshWindowsList()
    {
        Graphics g;            
        g = GraphicsfromImage(img);
        g.Clear(Color.White);
        ClearGraphics = true;
        this.listBoxSnap.Items.Clear();
        buttonSnap.Enabled = false;
        this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
        buttonSnap.Enabled = true;
        for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
        {
            string tt = listBoxSnap.Items[i].ToString();
            if (tt.Contains(" ,"))
            {
                listBoxSnap.Items.RemoveAt(i);
            }
        }
        rectangles = new Rectangle[listBoxSnap.Items.Count];
        isCropped = new bool[listBoxSnap.Items.Count];
        ConfirmRectangle.Enabled = false;
        textBoxIndex.Text = listBoxSnap.Items.Count.ToString();
        if (this.listBoxSnap.Items.Count > 0)
            this.listBoxSnap.SetSelected(0, true);
        listBoxSnap.Select();
        pictureBoxSnap.Invalidate();
    }

修改

一些小修正:

private void RefreshWindowsList()
    {
        //Graphics g; <- You dont need this         
        //g = GraphicsfromImage(img); <- You dont need this
        //g.Clear(Color.White); <- You dont need this
        //ClearGraphics = true; <- You dont need this
        this.listBoxSnap.Items.Clear();
        buttonSnap.Enabled = false;
        this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
        buttonSnap.Enabled = true;
        for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
        {
            string tt = listBoxSnap.Items[i].ToString();
            if (tt.Contains(" ,"))
            {
                listBoxSnap.Items.RemoveAt(i);
            }
        }
        rectangles = new Rectangle[listBoxSnap.Items.Count];
        isCropped = new bool[listBoxSnap.Items.Count];
        //ConfirmRectangle.Enabled = false; <- You dont need this
        textBoxIndex.Text = listBoxSnap.Items.Count.ToString();
        if (this.listBoxSnap.Items.Count > 0)
            this.listBoxSnap.SetSelected(0, true);
        listBoxSnap.Select();
        //pictureBoxSnap.Invalidate(); <- You dont need this
    }

private void DrawRectangle(Point pnt)替换为:

private void DrawRectangle(Point pnt)
    {
        Graphics g = Graphics.FromImage(img);

        g.DrawImage(imgClone, 0, 0);

        if (pnt.X == RectStartPoint.X || pnt.Y == RectStartPoint.Y)
        {
            g.DrawLine(Pens.Firebrick, RectStartPoint.X, RectStartPoint.Y, pnt.X, pnt.Y);
        }
        else
        {
            g.DrawRectangle(Pens.Firebrick, Math.Min(RectStartPoint.X, pnt.X), Math.Min(RectStartPoint.Y, pnt.Y), 
                            Math.Abs(RectStartPoint.X - pnt.X), Math.Abs(RectStartPoint.Y - pnt.Y));
        }

        g.Dispose();

        pictureBoxSnap.Invalidate();
}

private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)替换为:

private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
    {
        if (isCropped[listBoxSnap.SelectedIndex] == false && e.Button == MouseButtons.Left)
        {
            if (Math.Abs(e.Location.X - RectStartPoint.X) < 10 || Math.Abs(e.Location.Y - RectStartPoint.Y) < 10)
            {
                rectangles[listBoxSnap.SelectedIndex] = new Rectangle(0, 0, 0, 0);
                drawpicbox(listBoxSnap.SelectedIndex);
            }
            else
            {
                ConfirmRectangle.Enabled = true;
                rectangles[listBoxSnap.SelectedIndex] = new Rectangle(Math.Min(RectStartPoint.X, e.X), Math.Min(RectStartPoint.Y, e.Y),
                                Math.Abs(RectStartPoint.X - e.X), Math.Abs(RectStartPoint.Y - e.Y));
            }
        }
    }

一些解释:

功能calculateSizeAndPosition()(应该是calculateSize()),计算snap图片的新尺寸以适应图片框。它以类似于图片框缩放模式的方式计算它。

img是图片框始终在pictureBoxSnap.Invalidate();之后绘制的内容。因此,如果您想对图片框进行任何更改,请在img上绘制,然后使其无效。

瓦尔特