我是先把图像从服务器上下到本地,然后用PictureBox进行显示,并对其放大处理,下面是用来放大的类:
public class ZoomOut
{
static public Bitmap Zoom(Bitmap source,double n)
{
Bitmap bmp =new Bitmap(Convert.ToInt32(source.Width*n),Convert.ToInt32(source.Height*n));
    Graphics g = Graphics.FromImage(bmp);
Rectangle dest = new Rectangle(0,0,Convert.ToInt32(source.Width*n),Convert.ToInt32(source.Height*n));
Rectangle sour = new Rectangle(0,0,source.Width,source.Height);
g.DrawImage(source,dest,sour,System.Drawing.GraphicsUnit.Pixel);
g.Dispose();
return bmp;
}
下面是调用其对图像放大:
private void menuItemlarge1_Click(object sender, System.EventArgs e)
{
//Bitmap bmp = (Bitmap)pictureBox1.Image;
            Bitmap bmp = new Bitmap("\\_0001.bmp");
Bitmap bm = ZoomOut.Zoom(bmp,1.3);
            bmp.Dispose();
this.pictureBox1.Image =bm;
this.pictureBox1.Size = bm.Size;
this.vScrollBar1.Maximum = bm.Height + this.ClientSize.Height;
this.hScrollBar1.Maximum = bm.Width + this.ClientSize.Width;
this.hScrollBar1.Value = 0;
}
private void menuItemlarge2_Click(object sender, System.EventArgs e)
{   //Bitmap bmp = (Bitmap)pictureBox1.Image;
            Bitmap bmp = new Bitmap("\\_0001.bmp");
Bitmap bm = ZoomOut.Zoom(bmp,2.0);
            bmp.Dispose();
this.pictureBox1.Image = bm;
this.pictureBox1.Size = bm.Size;
this.vScrollBar1.Maximum = bm.Height + this.ClientSize.Height;
this.hScrollBar1.Maximum = bm.Width + this.ClientSize.Width;
this.hScrollBar1.Value = 0;
}
private void menuItemBack_Click(object sender, System.EventArgs e)
{
            Cursor.Current = Cursors.WaitCursor;
            this.pictureBox1.Refresh();
            Bitmap myBitmap= new Bitmap("\\_0001.bmp");
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pictureBox1.Image=(Image)myBitmap;
            Cursor.Current = Cursors.Default;
          }
这里运行后有两个问题:
1. 进行large1放大时,成功,但感觉不像放大了1.3倍的样子,像放大了2倍,然后接着进行large2放大,但每次到这里就提示OutOfMermoryException错误,怎么会内存溢出呢?难道是我的内存小的原因(我的是运行在智能手机上的程序)?要怎么解决呢?是我的程序的原因吗?
2. 如果我large1放大后,不进行large2放大,而是要返回原始图像(即放大前的,硬盘上的图像),但根本不行,我的程序不对吗?感觉很简单的呀?不就是把硬盘上的图像重新赋给PictureBox吗?为什么这么简单的程序却不行呢?哪里的错误呢?
上面的两个问题困扰我很长时间了,那位好心的大哥能帮帮我吗?感激涕零呀!!!

解决方案 »

  1.   

    不懂C#,不懂PictureBox不过有一点是肯定的。memory不是无限的。手机就更小了。而图像的大小几乎是无限的。
    换一个思路,你有一副图,要在屏幕上显示图像(或图像的一部分),这样你的内存需求只有一个图像的内存和一个屏幕的内存(这个可以更小)如果pictureBox只能画一个Bitmap。 你可以每次建立一个小的bitmap然后画这个小的bitmap.再准备一个小的。
    看你的code g.DrawImage 应该支持这个功能。注意:如果不能一次建立一个屏幕大小的内存可能有边缘问题。这个可能用你的方法无法解决。因为你的算法是别人写的。
      

  2.   

    我使用的是VC做的DLL,在DLL中进行缩放和显示,效率会好一些,但同样也会遇到原始图像尺寸过大导致无法载入问题。在这种情况下有关图像处理的API大多会失效,只有自己进行读取绘制等处理。
      

  3.   

    1。一开始我以为是bmp没释放的原因,所以加了一个bmp.Dispose()但仍然不行,还是提示有溢出。
    2。另外,为了方便,我只进行放大,没有进行缩小,想着放大了以后再把原始图像重新赋给PictureBox就可以了,客观就起到缩小的作用了,但不知问什么不行,唉
    3。我那个ZoomOut.Zoom()函数也可以进行缩小?n小于1时应该就是缩小,对吧
      

  4.   

    昨晚又运行了一下我的放大程序,才发现,原来那并不是放大,呜呜,因为我第一次给PictureBox1赋图像时,由于图像远大于PictureBox1的大小,所以我把PictureBox1的SizeMode属性设为StretchImage,这样就可以把图像以适应PictureBox1大小的方式显示,但我放大以后(即large1后),图像倒是大了,但原来是原来图像的大小,并不是放大1.3倍后的大小,就是说我放大以后根本没有起到作用,而只是把原图像按Normal的方式(即把SizeMode属性又改为Normal了)重新显示在PictureBox1中。难道我的放大程序有问题?但我记得以前曾经可以的,但最近调试就是老这样,唉,到底怎么回事?快崩溃了!!!!!
      

  5.   

    你是思路是从根本上错了..问题的根源不在于怎么新建,放大图像..如果你想让你的程序像Office图像管理器等那样,可以缩放显示图像. 你需要自己实现一个显示图像控件,根据显示的百分比,把图像绘制到窗体上,不管怎么改变比率..图努力是那一个..而不是像你想的这样...每次生成新图...在赋值给PictureBox.
      

  6.   

    1 放大缩小有现成的GDI+方法可以调用,不用自己写那么复杂的代码的.查一下DrawImage2 如果只是放大或者缩小"展示"一个图片的话,PictureBoxSizeMode.StretchImage就足够了,你要做的工作就是根据原始图片的尺寸等比例的设置图片控件的长和宽.
      

  7.   

    haiwangstar:
     不好意思,听不太懂您说的,难道我要自己从底层做一个独立的图像控件(类似于PictureBox的)?我是新手,唉,时间又紧,所以想在这个程序上做些许改动,但不知为什么原来可以的程序,现在为什么就不行了,很是纳闷。还望大哥多多指教,感激不尽。。
      

  8.   

    ki1381:
      1.我现在的这种方法不行吗?我查查DrawImage
      2.由于是用在手机上,图片控件的长和宽不能随意改变呀........唉
      

  9.   

          不太明白你的意思,随便写了放大图片的程序,希望帮到你。 
           private void Form1_Load(object sender, EventArgs e)
            {
                System.IO.MemoryStream ms=new System.IO.MemoryStream();
                System.Drawing.Image.FromFile(@"c:\test1.bmp").Save (ms,System.Drawing.Imaging.ImageFormat.Bmp);
                pictureBox1.Image = System.Drawing.Image.FromStream(ms);
                ms.Dispose();
                ms.Close();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Image img=pictureBox1.Image;
                System.IO.MemoryStream ms=new System.IO.MemoryStream();
                //  这里放大2倍,
                System.Drawing.Bitmap bmp = new Bitmap(img,img.Width*2,img.Height*2);
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
                pictureBox1.Image = System.Drawing.Image.FromStream(ms);
                ms.Dispose();
                ms.Close();
            }
      

  10.   

    难道我要自己从底层做一个独立的图像控件(自己绘一下图像就是底层?????? 核心就是说Image对象永远是那一个,,是不变的.变的只是绘制的方式..你这样每次生成图..不觉的非常低效,浪费吗..变的是绘制方式.而不是图..protected override OnPaint(PaintEventArgs e)
    {
       Graphics g = e.Graphics;
       g.DrawImage(...); 这里进行缩放绘制...
    }实在不行..在给你一个偷懒的方法..你把PictureBox设成同图同一比例,想要的大小 . 把PictureBox放在Panel中,让Panel自动滚动...
      

  11.   

    Bitmap   bmp   =   new   Bitmap("\\_0001.bmp"); 
    我把这句又换成Bitmap   bmp   =   (Bitmap)pictureBox1.Image; 
    然后使其可以放大缩小,并把pictureBox1的属性又换成Normal,在原图像大小上进行放大或缩小,感觉好一些了