C#的picturebox加载部分过大的图片,有时候无法显示或者内存溢出.

时间:2022-11-16 19:02:00
当使用picturebox显示一些图片文件
当图片文件比较大的时候
比如jpg分辨率很高,文件大概8-9M这样的时候
就会出现图片无法显示或者错误的情况


请问这样的情况需要怎么样才能pictrurebox里正常显示这个图片?

我个人的想法是把它按照比例压缩到固定的尺寸,然后显示压缩后的文件.
但是现在PICTUREBOX无法加载,请问这个代码应该怎么写?
比如,按照比例缩放到长最长为1024,宽最长为768,这种类似的代码应该怎么写?

还有,如果不压缩,可以不可以直接用GDI之类的方法把图片显示出来?
如果可以,代码应该怎么写?

6 个解决方案

#1


参考开源C#图片查看器。

#2


星期六高手都去旅游了?
就剩这种混分的了?

#3


我能说来混下分吗

#4


将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

#5


引用 4 楼 Chinajiyong 的回复:
将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

你好
非常感谢
,这个代码经过测试,缩放是可以的
但是有问题,不是很完美



            // <summary>
        /// 显示图片
        /// </summary>
        /// <param name="sBmp"></param>
        private void ShowPicture(Bitmap sBmp, pOffset poffset1, double dPictureShowScale)
        {
           
            if (sBmp == null)
                return;
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            //获取图像的BitmapData对像 
            BitmapData sData = sBmp.LockBits(new Rectangle(0, 0, sBmp.Width, sBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            Bitmap dBmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            BitmapData dData = dBmp.LockBits(new Rectangle(0, 0, dBmp.Width, dBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            //循环处理 
            //将项目的“可编译不安全代码”属性设置为true就可以了,方法如下:项目属性对话框——配置属性——生成——允许不安全代码块设置true
            unsafe
            {
                byte* ptrSource = (byte*)(sData.Scan0);
                byte* ptrDes = (byte*)(dData.Scan0);
                int nHeight = dData.Height / 2;
                int nWidth = dData.Width / 2;
                int nOIndexY = 0;
                int nOIndexX = 0;
               

                for (int y = 0; y < dData.Height; y++)
                {
                    nOIndexY = (int)Math.Round((poffset1.Y + y) / dPictureShowScale, 0, MidpointRounding.AwayFromZero);
                    for (int x = 0; x < dData.Width; x++)
                    {
                        int indexDes = 0;
                        int indexSource = 0;
                        nOIndexX = (int)Math.Round((poffset1.X + x) / dPictureShowScale, 0, MidpointRounding.AwayFromZero);
                        if (0 < nOIndexX && nOIndexX < sData.Width && 0 < nOIndexY && nOIndexY < sData.Height)
                        {
                            indexDes = y * dData.Stride + x * 3;
                            indexSource = nOIndexY * sData.Stride + nOIndexX * 3;
                            ptrDes[indexDes] = ptrSource[indexSource];
                            ptrDes[indexDes + 1] = ptrSource[indexSource + 1];
                            ptrDes[indexDes + 2] = ptrSource[indexSource + 2];
                        }
                    }
                }
                dBmp.UnlockBits(dData);
                sBmp.UnlockBits(sData);
            }
           
            pictureBox1.Image = dBmp;
            pictureBox1.Image.Save ( Application.StartupPath + "\\save.jpg");
          
        }


我不管是仅仅显示还是保存为图片
他只能显示PICTUREBOX里面缩放之后显示的内容
比如缩放以后比这个图片框小,那么剩下的位置都是黑色的,这些黑色的也保存再 dBmp里面.
如果比这个大,那就只显示图片框能显示的部分,
我把图片框设置成StretchImage或者autosize都不行.
请问能不能改进一下代码?

#6


引用 4 楼 Chinajiyong 的回复:
将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

已通过其他方法解决了问题
非常感谢.

#1


参考开源C#图片查看器。

#2


星期六高手都去旅游了?
就剩这种混分的了?

#3


我能说来混下分吗

#4


将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

#5


引用 4 楼 Chinajiyong 的回复:
将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

你好
非常感谢
,这个代码经过测试,缩放是可以的
但是有问题,不是很完美



            // <summary>
        /// 显示图片
        /// </summary>
        /// <param name="sBmp"></param>
        private void ShowPicture(Bitmap sBmp, pOffset poffset1, double dPictureShowScale)
        {
           
            if (sBmp == null)
                return;
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            //获取图像的BitmapData对像 
            BitmapData sData = sBmp.LockBits(new Rectangle(0, 0, sBmp.Width, sBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            Bitmap dBmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            BitmapData dData = dBmp.LockBits(new Rectangle(0, 0, dBmp.Width, dBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            //循环处理 
            //将项目的“可编译不安全代码”属性设置为true就可以了,方法如下:项目属性对话框——配置属性——生成——允许不安全代码块设置true
            unsafe
            {
                byte* ptrSource = (byte*)(sData.Scan0);
                byte* ptrDes = (byte*)(dData.Scan0);
                int nHeight = dData.Height / 2;
                int nWidth = dData.Width / 2;
                int nOIndexY = 0;
                int nOIndexX = 0;
               

                for (int y = 0; y < dData.Height; y++)
                {
                    nOIndexY = (int)Math.Round((poffset1.Y + y) / dPictureShowScale, 0, MidpointRounding.AwayFromZero);
                    for (int x = 0; x < dData.Width; x++)
                    {
                        int indexDes = 0;
                        int indexSource = 0;
                        nOIndexX = (int)Math.Round((poffset1.X + x) / dPictureShowScale, 0, MidpointRounding.AwayFromZero);
                        if (0 < nOIndexX && nOIndexX < sData.Width && 0 < nOIndexY && nOIndexY < sData.Height)
                        {
                            indexDes = y * dData.Stride + x * 3;
                            indexSource = nOIndexY * sData.Stride + nOIndexX * 3;
                            ptrDes[indexDes] = ptrSource[indexSource];
                            ptrDes[indexDes + 1] = ptrSource[indexSource + 1];
                            ptrDes[indexDes + 2] = ptrSource[indexSource + 2];
                        }
                    }
                }
                dBmp.UnlockBits(dData);
                sBmp.UnlockBits(sData);
            }
           
            pictureBox1.Image = dBmp;
            pictureBox1.Image.Save ( Application.StartupPath + "\\save.jpg");
          
        }


我不管是仅仅显示还是保存为图片
他只能显示PICTUREBOX里面缩放之后显示的内容
比如缩放以后比这个图片框小,那么剩下的位置都是黑色的,这些黑色的也保存再 dBmp里面.
如果比这个大,那就只显示图片框能显示的部分,
我把图片框设置成StretchImage或者autosize都不行.
请问能不能改进一下代码?

#6


引用 4 楼 Chinajiyong 的回复:
将原图片按指定的位置像素填充到目标图片,不知道行不行
参考 http://blog.csdn.net/tuxingzhou/article/details/44181313

已通过其他方法解决了问题
非常感谢.