为什么当我创建位图时,它是空的全白?

时间:2014-08-20 21:28:08

标签: c# .net winforms

private Bitmap CropImage()
        {
            Bitmap pic = pictureBoxSnap.Image as Bitmap;
            Bitmap cropped = new Bitmap(rect.Width, rect.Height);

            using (Graphics g = Graphics.FromImage(cropped))
            {
                g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
                             rect, GraphicsUnit.Pixel);
            }
            pic.Save(@"c:\temp\testingitimage.jpg");
            cropped.Save(@"c:\temp\testingitimage1.bmp");
            return cropped;

        }

我添加了两行Save以测试我得到的内容。第一张图片,我看到pictureBox中的正确图像。 但第二个被裁剪的是白色和空白。

我从pictureBox绘制事件中调用此方法:

private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
        {

            if (pictureBoxSnap.Image != null)
            {
                {
                    if (ClearGraphics == false)
                    {
                        if (cropRect == false)
                        {
                            if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
                            {
                                e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
                            }
                        }
                        else
                        {
                            if (rect.Width > 10 && rect.Height > 10)
                            {
                                e.Graphics.DrawRectangle(Pens.Gray, rect);
                                pictureBoxSnap.Image = CropImage();
                                Image img = CropImage();
                                img.Save(@"c:\temp\testimageing.jpg");
                            }
                        }
                    }
                }
            }           
        }

我在:e.Graphics.DrawRectangle(Pens.Gray,rect)上使用断点;并且rect不为空(rect是我在pictureBox上绘制的Rectangle,然后当我点击一个按钮时它会对pict​​ureBox进行验证)。

我也在这里做了一次保存并且在硬盘上看到它看起来是黑色但是当我用Paint编辑它时我看到它是空的。

例如,当我在pictureBox上绘制一个矩形时,我在CropImage方法中使用断点,我看到变量rect是例如:X = 136 Y = 149 Width = 131 Height = 106 同样在paint事件中,这个rec​​t变量具有相同的值。

图片框大小为:640x480 并且pictureBox属性SizeMode设置为:zoom

我为什么会得到空的白色图像?而不是包含图像部分的裁剪矩形?

编辑:

这是我现在使用的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;

namespace MinimizeCapture
{
    public partial class Form1 : Form
    {
        Boolean bHaveMouse;
        Point ptOriginal = new Point();
        Point ptLast = new Point();
        bool cropRect;
        Bitmap cloneBitmap;
        Rectangle recttest;
        private Rectangle Rect;
        private Rectangle[] rectangles;
        private Rectangle RectClone;
        private bool btn = false;
        private Point RectStartPoint = Point.Empty;
        private Point RectEndPoint = Point.Empty;
        private Brush selectionBrush = new SolidBrush(Color.Red);
        private Pen pen;
        private string selectedIndex;
        private List<string> drawnItems = new List<string>();
        private bool ClearGraphics;

        public Form1()
        {
            InitializeComponent();

            cropRect = false;
            var windows = OpenWindowGetter.FindWindowsWithText();
            ClearGraphics = false;
            this.DoubleBuffered = true;
            btn = false;
            pen = new Pen(selectionBrush);
            buttonSnap.Enabled = false;
            backgroundWorker1.RunWorkerAsync();
        }

        private void buttonSnap_Click(object sender, EventArgs e)
        {
            ClearGraphics = true;
            this.listBoxSnap.Items.Clear();
            this.pictureBoxSnap.Image = null;
            backgroundWorker1.RunWorkerAsync();
        }

        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;
                }
            }

        }

        private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
        {
            WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            rectangles = new Rectangle[listBoxSnap.Items.Count];
            buttonSnap.Enabled = true;
        }

        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 > 10 && recttest.Height > 10)
                        {
                            //e.Graphics.DrawRectangle(Pens.Gray, recttest);
                            e.Graphics.Clear(Color.White);
                            /*pictureBoxSnap.Image = CropImage();
                            Image img = CropImage();
                            img.Save(@"c:\temp\testimageing.jpg");*/

                        }
                    }
                }
            }           
        }

        private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
        {

            if (btn == true)
            {
                ClearGraphics = false;
                RectEndPoint = e.Location;
                int currentindex = listBoxSnap.SelectedIndex;
                rectangles[currentindex] = RectClone;
                Rect = getRect(RectStartPoint, RectEndPoint);
                RectClone = Rect;
                pictureBoxSnap.Invalidate();
            }

            Point ptCurrent = new Point(e.X, e.Y);
        // If we "have the mouse", then we draw our lines.
            if (bHaveMouse)
            {
                // If we have drawn previously, draw again in
                // that spot to remove the lines.
                if (ptLast.X != -1)
                {
                    MyDrawReversibleRectangle(ptOriginal, ptLast);
                }
                // Update last point.
                ptLast = ptCurrent;
                // Draw new lines.
                MyDrawReversibleRectangle(ptOriginal, ptCurrent);
            }
        }

        private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
        {
            RectStartPoint = e.Location;
            btn = true;
            Rect = Rectangle.Empty;
            RectClone = Rectangle.Empty;

            bHaveMouse = true;
            // Store the "starting point" for this rubber-band rectangle.
            ptOriginal.X = e.X;
            ptOriginal.Y = e.Y;
            // Special value lets us know that no previous
            // rectangle needs to be erased.
            ptLast.X = -1;
            ptLast.Y = -1;
        }

        private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
        {
            recttest = rectangles[listBoxSnap.SelectedIndex];
            ClearGraphics = false;
            btn = false;
            RectEndPoint = e.Location;
            pictureBoxSnap.Invalidate();
            int currentindex = listBoxSnap.SelectedIndex;
            rectangles[currentindex] = RectClone;

            // Set internal flag to know we no longer "have the mouse".
            bHaveMouse = false;
            // If we have drawn previously, draw again in that spot
            // to remove the lines.
            if (ptLast.X != -1)
            {
                Point ptCurrent = new Point(e.X, e.Y);
                MyDrawReversibleRectangle(ptOriginal, ptLast);
            }
            // Set flags to know that there is no "previous" line to reverse.
            ptLast.X = -1;
            ptLast.Y = -1;
            ptOriginal.X = -1;
            ptOriginal.Y = -1;
            pictureBoxSnap.Invalidate();
        }

        Rectangle getRect(Point p1, Point p2)
        {
            Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
            Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
            return new Rectangle(p, s);
        }

        private void ConfirmRectangle_Click(object sender, EventArgs e)
        {
            ConfirmRectangle.ForeColor = Color.Red;
            ConfirmRectangle.Enabled = false;
            StreamWriter w = new StreamWriter(@"c:\temp\Settings.txt", true);
            w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
            textBoxIndex.Text = selectedIndex.ToString();
            w.Close();
            cropRect = false;
            //pictureBoxSnap.Invalidate();
            Image img = CropImage();
            img.Save(@"c:\temp\testimageing.jpg");
            pictureBoxSnap.Image = img;

        }

        // Convert and normalize the points and draw the reversible frame.
        private void MyDrawReversibleRectangle(Point p1, Point p2)
        {
            Rectangle rc = new Rectangle();
            // Convert the points to screen coordinates.
            p1 = pictureBoxSnap.PointToScreen(p1);
            p2 = pictureBoxSnap.PointToScreen(p2);
            // Normalize the rectangle.
            if (p1.X < p2.X)
            {
                rc.X = p1.X;
                rc.Width = p2.X - p1.X;
            }
            else
            {
                rc.X = p2.X;
                rc.Width = p1.X - p2.X;
            }
            if (p1.Y < p2.Y)
            {
                rc.Y = p1.Y;
                rc.Height = p2.Y - p1.Y;
            }
            else
            {
                rc.Y = p2.Y;
                rc.Height = p1.Y - p2.Y;
            }
            // Draw the reversible frame.
            rect = new Rectangle(pictureBoxSnap.PointToClient(rc.Location), rc.Size);
            ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
        }

        Rectangle rect = Rectangle.Empty;

        private Bitmap CropImage()
        {
            //rect = recttest;
            Bitmap pic = pictureBoxSnap.Image as Bitmap;
            Bitmap cropped = new Bitmap(rect.Width, rect.Height);

            using (Graphics g = Graphics.FromImage(cropped))
            {
                g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
                             rect, GraphicsUnit.Pixel);
            }
            pic.Save(@"c:\temp\testingitimage.jpg");
            cropped.Save(@"c:\temp\testingitimage1.bmp");
            return cropped;

        }
    }
}

从绘画中移动CropImage调用方法并将其添加到按钮单击此处:

private void ConfirmRectangle_Click(object sender, EventArgs e)
        {
            ConfirmRectangle.ForeColor = Color.Red;
            ConfirmRectangle.Enabled = false;
            StreamWriter w = new StreamWriter(@"c:\temp\Settings.txt", true);
            w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
            textBoxIndex.Text = selectedIndex.ToString();
            w.Close();
            cropRect = false;
            //pictureBoxSnap.Invalidate();
            Image img = CropImage();
            img.Save(@"c:\temp\testimageing.jpg");
            pictureBoxSnap.Image = img;

        }

这一行:

Image img = CropImage();
img.Save(@"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;

但是我在pictureBox中得到的是:

eZoom in ?

不确定原因。矩形处于我绘制它的位置,但显示原始图像的一部分在矩形中切割,它就像放大一样。

2 个答案:

答案 0 :(得分:1)

你正在多次裁剪。

pictureBoxSnap.Image = CropImage();    // First Time
Image img = CropImage();               // Second Time
img.Save(@"c:\temp\testimageing.jpg");

你只需要裁剪一次。在这里,您使用相同的图片框作为源和裁剪图像。第一次裁剪然后图像。裁剪后的图像将正确设置到图片框中。但是,第二次应用程序将尝试再次裁剪该图像。

你应该这样做

Image img = CropImage();    
img.Save(@"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;

答案 1 :(得分:0)

private Bitmap CropImage(){
    Bitmap pic = pictureBoxSnap.Image as Bitmap;
    Bitmap cropped = new Bitmap(rect.Width, rect.Height);

    using (Graphics g = Graphics.FromImage(cropped)){
        g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
                         rect, GraphicsUnit.Pixel);
    }

    using (Graphics g = Graphics.FromImage(pic)){
        g.DrawImage(cropped , 136, 149, rect.Width, rect.Height);
        //Draw the rectangle
    }

    //pic.Save(@"c:\temp\testingitimage.jpg");
    //cropped.Save(@"c:\temp\testingitimage1.bmp");
    return pic;
}

瓦尔特