http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 12502|回复: 24

[学生提问] Graphics.DrawImage 方法连续放大图层反而缩小了

[复制链接]
发表于 2014-9-10 17:54:18 | 显示全部楼层 |阅读模式
1金钱
如题,我使用的是Graphics.DrawImage 方法 (Image, Rectangle, Rectangle, GraphicsUnit)拖出一个矩形框放大,第一次放大很成功,将矩形框内容放大成之前的整个图层的尺寸,但在此基础上连续第二次放大则反而变小了
[C#] 纯文本查看 复制代码
                    smallmap = new Bitmap(bmp, pictureBox1.Width, pictureBox1.Height);

                    graphics = pictureBox1.CreateGraphics();//图形创建
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.Clear(Color.White);
               
                    Rectangle D = new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height);//何必创两个矩形?
                    Rectangle C = new Rectangle(start.X, start.Y, w, h);//D是放大前的图形,C是放大后的图形
                    graphics.DrawImage(smallmap, D, C, GraphicsUnit.Pixel);


                    graphics.Dispose();

这是部分代码,求大神指教



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2014-9-10 18:10:03 | 显示全部楼层
你调试看看,应该是中间代码有问题。我估计是逻辑问题
回复

使用道具 举报

 楼主| 发表于 2014-9-10 18:56:42 | 显示全部楼层
站长苏飞 发表于 2014-9-10 18:10
你调试看看,应该是中间代码有问题。我估计是逻辑问题

调了的,大致问题就是在第二次放大的时候,我拖出的矩形框还是建立在最初的图层上的,而不是放大后的图层上的
回复

使用道具 举报

发表于 2014-9-10 19:21:41 | 显示全部楼层
那安逻辑就是第二次的没有存储成功吧
回复

使用道具 举报

发表于 2014-9-11 09:40:19 | 显示全部楼层
楼主需要将第一次放大的图做临时存储然后和从新赋值给picturebox,然后第二次放大的时候再以picturebox图为基础方法即可,这个之前遇到过相同的问题,目前我是这么解决的,祝楼主好运
回复

使用道具 举报

 楼主| 发表于 2014-9-11 19:46:00 | 显示全部楼层
ching126 发表于 2014-9-11 09:40
楼主需要将第一次放大的图做临时存储然后和从新赋值给picturebox,然后第二次放大的时候再以picturebox图为 ...

谢谢,我试试
回复

使用道具 举报

 楼主| 发表于 2014-9-13 00:33:33 | 显示全部楼层
ching126 发表于 2014-9-11 09:40
楼主需要将第一次放大的图做临时存储然后和从新赋值给picturebox,然后第二次放大的时候再以picturebox图为 ...

亲,我没弄成功,你能发个事例代码给我吗···我如何把smallmap替换成矩形框出来的图
回复

使用道具 举报

发表于 2014-9-13 10:26:43 | 显示全部楼层
我这个是有5个小图片框,然后选中一个之后再将选中的图像加载到大图片框中,然后在大图片框汇总选择一块区域填充到刚才选中了小图片框中,至于你的事放大,则需要等图片等比例放大即可,下面是实例代码,您可以安装您的需要修改,这个是将图片打开到图片框
private void btnOpenImage_Click(object sender, EventArgs e)
        {
            //图像比原图缩小了40%,缩到60%的大小了
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.AddExtension = true;
            ofd.Multiselect = true;
            ofd.DefaultExt = "jpg|bmp";
            ofd.Filter = "bmp files (*.bmp)|*.bmp|jpg files (*.jpg)|*.jpg";  //|All files(*.*)|*.*
            ofd.FilterIndex = 1;
            int index = 0;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                PictureBox tempPicb = null;
                Label tempLabel = null;
                CheckBox tempChk = null;
                //Random rand = new Random();
                //int n = rand.Next(1, 999);
                if (ht.Count <= 0)  //pb == null &&
                {
                    for (int i = 0; i < ofd.FileNames.Length; i++)
                    {
                        tempPicb = SelectedPictureBox(i + 1);
                        tempLabel = GetCurrentLabel(i + 1);
                        tempChk = GetCurrentCheckBox(i + 1);

                        tempPicb.SizeMode = PictureBoxSizeMode.Zoom;
                        tempPicb.Image = Image.FromFile(ofd.FileNames[i]);

                        //n = rand.Next(1, 999) == n ? rand.Next(1, 999) : n;
                        //tempLabel.Text = n + "_" + ofd.SafeFileNames[i];  // + ofd.DefaultExt;
                        tempLabel.Text = ofd.SafeFileNames[i];  // + ofd.DefaultExt;
                        tempChk.Checked = true;
                    }
                }
                else if (ht.Count <= 1)
                {
                    //这里只是修改一个或者替换一个图像
                    foreach (DictionaryEntry de in ht)
                    {
                        tempPicb = (PictureBox)de.Value;
                        tempLabel = GetCurrentLabel(Convert.ToInt32(de.Key));
                        tempChk = GetCurrentCheckBox(Convert.ToInt32(de.Key));

                        tempPicb.SizeMode = PictureBoxSizeMode.Zoom;
                        tempPicb.Image = Image.FromFile(ofd.FileNames[index]);
                        
                        //n = rand.Next(1, 999) == n ? rand.Next(1, 999) : n;
                        //tempLabel.Text = n + "_" + ofd.SafeFileNames[index];
                        tempLabel.Text = ofd.SafeFileNames[index];
                        tempChk.Checked = true;

                        picbOriginalImage.SizeMode = PictureBoxSizeMode.Zoom;
                        picbOriginalImage.Image = tempPicb.Image;
                        lbImageName.Text = tempLabel.Text;
                    }
                }
                else  //if (ht.Count > 1)
                {
                    foreach (DictionaryEntry de in ht)
                    {
                        tempPicb = (PictureBox)de.Value;
                        tempLabel = GetCurrentLabel(Convert.ToInt32(de.Key));
                        tempChk = GetCurrentCheckBox(Convert.ToInt32(de.Key));

                        tempPicb.SizeMode = PictureBoxSizeMode.Zoom;
                        tempPicb.Image = Image.FromFile(ofd.FileNames[index]);

                        //n = rand.Next(1, 999) == n ? rand.Next(1, 999) : n;
                        //tempLabel.Text = n +"-" + ofd.SafeFileNames[index];
                        tempLabel.Text = ofd.SafeFileNames[index];
                        tempChk.Checked = true;

                        index++;
                        if (index >= ofd.FileNames.Length)
                        {
                            break;
                        }
                    }
                }
                //ht.Clear();

                tempPicb = null;
            }
        }
图片框的选中
/// <summary>
        /// 图像的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PictureBox_Click(object sender, EventArgs e)
        {
            object tag = ((PictureBox)sender).Tag;
            g_i_Flag = Convert.ToInt32(tag);
            //Image image = null;
            //pb = (PictureBox)sender;  //将选中的对象给pb
            PictureBox tempPb = (PictureBox)sender;
            pb = tempPb;
            if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
            {
                //MessageBox.Show("Ctrl键被按下");
                //选中时改变样式
                SelectedPictureBoxToStyle(g_i_Flag, true);
                ht.Remove(tag);
                ht.Add(tag, tempPb);  //如果按下ctrl键选中那个添加那个
            }
            else
            {
                //移除所有之前选中的图像
                ht.Clear();
                ht.Add(tag, tempPb);
                pictureBox1.BorderStyle = BorderStyle.FixedSingle;
                pictureBox2.BorderStyle = BorderStyle.FixedSingle;
                pictureBox3.BorderStyle = BorderStyle.FixedSingle;
                pictureBox4.BorderStyle = BorderStyle.FixedSingle;
                pictureBox5.BorderStyle = BorderStyle.FixedSingle;
                //((PictureBox)sender).BorderStyle = BorderStyle.Fixed3D;
                SelectedPictureBoxToStyle(g_i_Flag, true);
                lb = GetCurrentLabel(g_i_Flag);
                //image = pb.Image;
                //pb = null;
                if (tempPb.Image == null)
                    return;
                //panel1.BackgroundImage = Image.FromFile(opf.FileName);
                g_img_image = tempPb.Image;
                picbOriginalImage.SizeMode = PictureBoxSizeMode.Zoom;
                picbOriginalImage.Image = g_img_image;
                lbImageName.Text = lb.Text;

                srcImage = g_img_image;
                srcWidth = srcImage.Width;
                srcHeight = srcImage.Height;

                thumbWidth = picbOriginalImage.Width;
                thumbHeight = picbOriginalImage.Height;
               
            }
            
            
            tempPb = null;
        }
鼠标按下事件
/// <summary>
        /// 鼠标在图像上按下事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                //记录鼠标按下时的坐标位置
                startPosX = e.X;
                startPosY = e.Y;
                isDraw = true;

                //这里需要界定当鼠标按下的是左键时,鼠标区域控制,不能出picturebox框
                //Point point = this.PointToScreen(new Point(19, 203));  //将窗体计算成屏幕坐标
                Point point = this.PointToScreen(groupBox2.Location);  //将窗体计算成屏幕坐标
                point.X = point.X + picbOriginalImage.Location.X;
                point.Y = point.Y + picbOriginalImage.Location.Y;
                int offsetX = groupBox2.Location.X + picbOriginalImage.Location.X;
                int offsetY = groupBox2.Location.Y + picbOriginalImage.Location.Y;

                //Point point = new Point(100, 100);
                //Point point = this.PointToClient(new Point(0, 0));  //将屏幕坐标计算成窗体
                //this.ClientRectangle.Width, this.ClientRectangle.Height
                Rectangle rect = new Rectangle(point, new Size(this.ClientSize.Width - offsetX - 125, this.ClientSize.Height - offsetY - 17));
                Cursor.Clip = rect;
                //MessageBox.Show(picbOriginalImage.Location.X + "," + picbOriginalImage.Location.Y + ";"
                //+ groupBox2.Location.X + "," + groupBox2.Location.Y);
            }
            else
            {
                //说明按下的不是左键而是右键,这时需要重绘控件和子控件
                Refresh();
            }
        }
鼠标在图像上抬起事件
/// <summary>
        /// 鼠标在图像上抬起事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_MouseUp(object sender, MouseEventArgs e)
        {
            isDraw = false;
            g.Dispose();
            bool isReplaceImage = false;
            #region
            //将原图绘制成大小适中的小图
            //Bitmap srcBmp = new Bitmap(srcWidth, srcHeight, PixelFormat.Format32bppArgb);
            //Graphics srcG = Graphics.FromImage(srcBmp);
            //srcG.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //srcG.SmoothingMode = SmoothingMode.AntiAlias;
            //srcG.DrawImage(srcImage, Point.Empty);
            //srcG.Flush();  //FlushIntention.Flush

            ////再选取小图中的区域
            //Bitmap dstBmp = new Bitmap(dstWidth, dstHeight, PixelFormat.Format32bppArgb);
            //Graphics dstG = Graphics.FromImage(dstBmp);
            //dstG.DrawImage(srcBmp, 0, 0, new Rectangle(X, Y, dstWidth, dstHeight), GraphicsUnit.Pixel);
            //dstG.Flush();

            //dstG.Dispose();

            //dstImage = dstBmp;

            //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            //pictureBox1.Image = dstImage;
            #endregion

            //这里需要界定,当鼠标抬起时解除鼠标区域控制
            Screen[] srceens = Screen.AllScreens;
            Cursor.Clip = srceens[0].Bounds;

            if (e.Button == System.Windows.Forms.MouseButtons.Right)
                return;
            if (dstWidth <= 27 || dstHeight <= 20)
            {
                //MessageBox.Show("所选区域宽度不能小于27像素,高度不能小于20像素!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //如果pb==null的话说明没有选中picturebox
            if (pb == null)
            {
                return;
            }
            else
            {
                //说明选中了其中的picturebox,在判断选中的picturebox有没有image
                //if (pb.Image != null)
                //{
                //    if (MessageBox.Show("确定要替换打印 " + g_i_Flag + " 的原图像吗?", "提示", MessageBoxButtons.OKCancel,
                //            MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.OK)
                //    {
                //        isReplaceImage = true;
                //    }
                //    else
                //    {
                //        isReplaceImage = false;
                //    }
                //}
                //else
                //{
                //    isReplaceImage = true;
                //}
                isReplaceImage = true;
            }

            //说明需要替换
            if (isReplaceImage)
            {
                DrawSelectedImage();
            }

            //pb = null;

        }
鼠标在图片上移动事件
/// <summary>
        /// 鼠标在图像上移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_MouseMove(object sender, MouseEventArgs e)
        {
            endPosX = e.X;
            endPosY = e.Y;

            if (isDraw)
            {
                Refresh();
                //picbOriginalImage.Invalidate();
            }
        }
/// <summary>
        /// 绘画
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Image_Paint(object sender, PaintEventArgs e)
        {
            //if (pb == null)
            g = e.Graphics;
            //g = picbOriginalImage.CreateGraphics();
            //if (image == null)
            //    return;
            //g = Graphics.FromImage(image);
            //else
            //g = pb.CreateGraphics();
            if (isDraw)
            {
                //设置虚线格式
                //Dash短线段,DashDot短线段和点,DashDotDot短线段点点,Dot点,Solid实线
                pen.DashStyle = DashStyle.Dash;
                //设置宽度和高度
                dstWidth = endPosX - startPosX;
                dstHeight = endPosY - startPosY;
                //if (picbOriginalImage.Image == null)
                //    return;
                //判断开始点结束点是从哪个方向到哪个方向
                if (dstWidth < 0 && dstHeight < 0)
                {
                    X = endPosX;
                    Y = endPosY;
                    dstWidth = Math.Abs(dstWidth);
                    dstHeight = Math.Abs(dstHeight);
                }
                else if (dstWidth < 0)
                {
                    X = endPosX;
                    Y = startPosY;
                    dstWidth = Math.Abs(dstWidth);
                }
                else if (dstHeight < 0)
                {
                    X = startPosX;
                    Y = endPosY;
                    dstHeight = Math.Abs(dstHeight);
                }
                else
                {
                    X = startPosX;
                    Y = startPosY;
                }

                //目标矩形
                Rectangle dstRectangle = new Rectangle(X, Y, dstWidth, dstHeight);
                //这个是使用图像填充内部
                //TextureBrush texture = new TextureBrush(srcImage);
                //texture.WrapMode = WrapMode.Tile;

                //画图像,这里需要填充到上面选中的框中
                //g.DrawImageUnscaledAndClipped(image, dstRectangle);

                //给矩形画填充内容
                //g.DrawImage(srcImage, X, Y, dstRectangle, GraphicsUnit.Pixel);
                //给矩形填充内容
                //g.FillRectangle(texture, dstRectangle);

                //画矩形框
                g.DrawRectangle(pen, dstRectangle);

            }
        }
为刚才选区填充图像
/// <summary>
        /// 为选中的区域填充图像
        /// </summary>
        private void DrawSelectedImage()
        {
            try
            {
                //将原图绘制成大小适中的小图
                Bitmap thumbBmp = new Bitmap(thumbWidth, thumbHeight, PixelFormat.Format32bppArgb);
                Graphics thumbG = Graphics.FromImage(thumbBmp);

                thumbG.InterpolationMode = InterpolationMode.High;
                thumbG.SmoothingMode = SmoothingMode.HighQuality;
                thumbG.CompositingQuality = CompositingQuality.HighQuality;

                Rectangle thumbRectangle = new Rectangle(0, 0, thumbWidth, thumbHeight);
                thumbG.DrawImage(srcImage, thumbRectangle, 0, 0, srcWidth, srcHeight, GraphicsUnit.Pixel);
                thumbG.Flush();  //FlushIntention.Flush
                thumbG.Dispose();

                //再选取小图中的区域
                Bitmap dstBmp = new Bitmap(dstWidth, dstHeight, PixelFormat.Format32bppArgb);
                Graphics dstG = Graphics.FromImage(dstBmp);
                Rectangle dstRectangle = new Rectangle(X, Y, dstWidth, dstHeight);
                dstG.DrawImage(thumbBmp, 0, 0, dstRectangle, GraphicsUnit.Pixel);
                dstG.Flush();
                dstG.Dispose();

                dstImage = dstBmp;

                //ImageToSelectedPictureBox(g_i_Flag);
                //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                //pictureBox1.Image = dstImage;
                //((PictureBox)((object)(pb.Name))).SizeMode = PictureBoxSizeMode.Zoom;
                //((PictureBox)((object)(pb.Name))).Image = dstImage;
                pb.SizeMode = PictureBoxSizeMode.Zoom;
                pb.Image = dstImage;
                //dstImage = null;
                //thumbBmp.Dispose();
                thumbBmp = null;
                //dstBmp.Dispose();
                dstBmp = null;
            }
            catch (Exception)
            {
                //
            }
        }
我这个最后返回的是image,您可以保存也可以做处理都可以
回复

使用道具 举报

发表于 2014-9-13 10:29:42 | 显示全部楼层
我的是5个图片框,对应有5个label,用来临时存储打开的图片的名称,然后选中那个绘制矩形之后需要保存的,还要有图片名称,所有以上代码您可以自己优化下
回复

使用道具 举报

 楼主| 发表于 2014-9-13 20:54:00 | 显示全部楼层
ching126 发表于 2014-9-13 10:29
我的是5个图片框,对应有5个label,用来临时存储打开的图片的名称,然后选中那个绘制矩形之后需要保存的,还 ...

收到了,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-6-12 18:44

© 2014-2021

快速回复 返回顶部 返回列表