当前位置:编程学习 > C#/ASP.NET >>

图片转换太慢了啊...有没有更快的方法?

图片转换太慢了啊...有没有更快的方法?

目的:将一个较大的图片文件转换成较小的图片显示在PictureBox中。

文件一般jpg格式,几MB不等,图片大小为几千x几千,例如8000x4000。要按图片比例缩小,比如缩小到2000x1000,然后显示到PictureBox中。

我的方法是先用Image.FromFile方法载入文件,得到原始图片大小W0xH0,然后计算成比例缩小后的大小W1xH1。
再用new Bitmap(Image,W1,H1)的方法得到较小的图片用于显示。

现在的问题是new Bitmap的这个操作很费时,一般在数百毫秒甚至超过一秒。有没有更快的方法?

另:因为要同时显示多幅图片,直接将文件调入PictureBox再按比例缩小显示的方法很消耗内存,故没有采用。 --------------------编程问答-------------------- 不需要转换的,在PictureBox控件中显示图片,PictureBox控件带有这个功能的,只要需要设置PictureBox1.SizeModel=PictureBoxSizeMode.Zoom就可以了 --------------------编程问答-------------------- 你也可以在文件夹里放上大图片对应的缩小版的图片啊,在需要读取小图片的时候就直接读取小图片啊。。。 --------------------编程问答--------------------
引用 1 楼 lizhi3186575 的回复:
不需要转换的,在PictureBox控件中显示图片,PictureBox控件带有这个功能的,只要需要设置PictureBox1.SizeModel=PictureBoxSizeMode.Zoom就可以了


我在问题中提到了这个方法,但没有使用。
虽然PictureBox可以缩小显示大图片,但PictureBox扔保持原尺寸图片的数据,内存消耗很大。如果显示多个图片,会显示内存不足。
我的做法是先得到一个较小尺寸的图片再给PictureBox显示,这样内存消耗较小。只是得到较小图片的操作很费时间。有没有更好的方法? --------------------编程问答-------------------- 图片上传时 就生成多个尺寸的图片 --------------------编程问答--------------------
引用 2 楼 dixh1989 的回复:
你也可以在文件夹里放上大图片对应的缩小版的图片啊,在需要读取小图片的时候就直接读取小图片啊。。。


读取的大图片不是自己的,所以没有对应的缩小版图片。 --------------------编程问答--------------------
引用 4 楼 mmm306306 的回复:
图片上传时 就生成多个尺寸的图片


不存在上传的问题,是用于查看和分析的工具,图片在本地,是任意的。 --------------------编程问答--------------------  bp = (Bitmap)bp.GetThumbnailImage(W1,H1, myCallback, IntPtr.Zero)

这个会快点吗?? --------------------编程问答--------------------
引用 3 楼 bebeing 的回复:
Quote: 引用 1 楼 lizhi3186575 的回复:

不需要转换的,在PictureBox控件中显示图片,PictureBox控件带有这个功能的,只要需要设置PictureBox1.SizeModel=PictureBoxSizeMode.Zoom就可以了


我在问题中提到了这个方法,但没有使用。
虽然PictureBox可以缩小显示大图片,但PictureBox扔保持原尺寸图片的数据,内存消耗很大。如果显示多个图片,会显示内存不足。
我的做法是先得到一个较小尺寸的图片再给PictureBox显示,这样内存消耗较小。只是得到较小图片的操作很费时间。有没有更好的方法?

你之所以会显示内存不足,主要是你在切换图片显示的时候没有释放掉上一张图片的资源了,没有释放的话就所有图片都加载在内存中,当然会提示内存不足了,你可以再切换之前调用Image.Dispose方法就没有这样的问题了 --------------------编程问答--------------------
引用 7 楼 sosoben 的回复:
 bp = (Bitmap)bp.GetThumbnailImage(W1,H1, myCallback, IntPtr.Zero)

这个会快点吗??


这个也试过,速度也不快。 --------------------编程问答-------------------- lizhi3186575 
Learning_Hard :

我不是一次显示一个图片,而是同时显示多个图片。 --------------------编程问答-------------------- 如果都是jpg图片。GetThumbnailImage这个方法是挺不错的。
不过不能用.net自带的。
搜一下jpg格式。用jpg格式读出这个挺简单速度也相当快。
我以前帮别人做的一个排版的系统。读取写真照片就用这个方法。 --------------------编程问答-------------------- 是第一次读取图片慢,还是读完图片后进行转换操作慢? --------------------编程问答-------------------- 每次加载并缩小一个图的思路是正确的。
IO操作没什么好优化的方法,2000*1000 也不是个很大的尺寸,如果太慢, 你换个机机试一下。一秒左右确实慢得太过份了 --------------------编程问答-------------------- 1加内存,通过硬件来解决;
2优化程序,每次将大图等比缩小后存储一份,第一次加载的时候慢,第二次像对就较快;
3调整显示模式,增加等待加载提示,让用户体验相对较好; --------------------编程问答--------------------
引用 11 楼 zanfeng 的回复:
如果都是jpg图片。GetThumbnailImage这个方法是挺不错的。
不过不能用.net自带的。
搜一下jpg格式。用jpg格式读出这个挺简单速度也相当快。
我以前帮别人做的一个排版的系统。读取写真照片就用这个方法。

不用.net自带的,用哪个啊??? --------------------编程问答--------------------
引用 15 楼 sosoben 的回复:
Quote: 引用 11 楼 zanfeng 的回复:

如果都是jpg图片。GetThumbnailImage这个方法是挺不错的。
不过不能用.net自带的。
搜一下jpg格式。用jpg格式读出这个挺简单速度也相当快。
我以前帮别人做的一个排版的系统。读取写真照片就用这个方法。

不用.net自带的,用哪个啊???


自己去写啊。好象系统也提供了这个API。。 --------------------编程问答--------------------
引用 12 楼 yanghl1998 的回复:
是第一次读取图片慢,还是读完图片后进行转换操作慢?


从文件读取速度还可以,是读完图片后转换操作(大图转小图)慢。 --------------------编程问答--------------------
引用 11 楼 zanfeng 的回复:
如果都是jpg图片。GetThumbnailImage这个方法是挺不错的。
不过不能用.net自带的。
搜一下jpg格式。用jpg格式读出这个挺简单速度也相当快。
我以前帮别人做的一个排版的系统。读取写真照片就用这个方法。


客户的图片不只是jpg格式的。 --------------------编程问答--------------------
引用 13 楼 zhoujk 的回复:
每次加载并缩小一个图的思路是正确的。
IO操作没什么好优化的方法,2000*1000 也不是个很大的尺寸,如果太慢, 你换个机机试一下。一秒左右确实慢得太过份了


电脑确实不太先进啊,廉价的办公电脑。 --------------------编程问答--------------------
引用 17 楼 bebeing 的回复:
Quote: 引用 12 楼 yanghl1998 的回复:

是第一次读取图片慢,还是读完图片后进行转换操作慢?


从文件读取速度还可以,是读完图片后转换操作(大图转小图)慢。

如果你用 Graphics 进行 DrawImage的话,不慢才怪。类似如下代码:

       Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);
        using (Graphics graphics = Graphics.FromImage(newImage))
        {
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.DrawImage(image, 0, 0, newWidth, newHeight);
        }


采用这种试试:


private static byte BytesPerPixel(PixelFormat px)
{
    switch (px)
    {
        case PixelFormat.Format16bppRgb555:
        case PixelFormat.Format16bppRgb565:
        case PixelFormat.Format16bppGrayScale:
        case PixelFormat.Format16bppArgb1555: return 2;
        case PixelFormat.Format24bppRgb: return 3;
        case PixelFormat.Format32bppRgb: return 4;
        case PixelFormat.Format32bppArgb: return 4;
        case PixelFormat.Format32bppPArgb: return 4;
    }
    return 0;
}

public static Bitmap ThumbnailLow(Bitmap img, Size sz)
{
    if (img == null || sz.IsEmpty) return null;
    if (sz.Width > img.Width) sz = new Size(img.Width, sz.Height);
    if (sz.Height > img.Height) sz = new Size(sz.Width, img.Height);
    PixelFormat px = img.PixelFormat;
    PixelFormat pxn = PixelFormat.Format16bppRgb565;
    if (px == PixelFormat.Format32bppArgb || px == PixelFormat.Format32bppPArgb ||
        px == PixelFormat.Format32bppRgb) pxn = PixelFormat.Format24bppRgb;
    byte bytesPerPixel = BytesPerPixel(px), bytesPerPixel2 = BytesPerPixel(pxn);
    Bitmap nueva = new Bitmap(sz.Width, sz.Height, pxn);
    BitmapData bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, px);
    BitmapData bmpData2 = nueva.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadWrite, pxn);
    // 快速转换
    float inc_djn = img.Width / (float)sz.Width;
    float inc_din = img.Height / (float)sz.Height;
    float din = 0, djn = 0;
    bool _16bits = bytesPerPixel == 2 || bytesPerPixel2 == 2;
    unsafe
    {
        byte* ptr = (byte*)(bmpData.Scan0);
        byte* ptr2 = (byte*)(bmpData2.Scan0);
        int nOffset = bmpData.Stride - (bmpData.Width * bytesPerPixel);
        int nOffset2 = bmpData2.Stride - (bmpData2.Width * bytesPerPixel2);
        int h = bmpData.Height, w = bmpData.Width;
        for (int i = 0; i < h; i++)
        {
            bool lok = i >= din;
            djn = 0;
            for (int j = 0; j < w; j++)
            {
                if (lok && j >= djn)
                {
                    ptr2[0] = ptr[0];
                    ptr2[1] = ptr[1];
                    if (!_16bits) ptr2[2] = ptr[2];
                    ptr2 += bytesPerPixel2;
                    djn += inc_djn;
                }
                ptr += bytesPerPixel;
            }
            if (lok) { ptr2 += nOffset2; din += inc_din; }
            ptr += nOffset;
        }
    }
    img.UnlockBits(bmpData);
    nueva.UnlockBits(bmpData2);
    return nueva;
}


测试上述方法

  sw.Start();
  Image i1 = ThumbnailLow(img, new Size(100, 100)); 
  sw.Stop();//  
  sw2.Start();
  Image i2 = img.GetThumbnailImage(100, 100, null, IntPtr.Zero); 
  sw2.Stop(); // 正常情况,应该ThumbnailLow 比GetThumbnailImage 快一倍

--------------------编程问答-------------------- 不错不错!!!! --------------------编程问答--------------------  sw 和 sw2 是  Stopwatch ,忘了贴上
Stopwatch sw = new Stopwatch();
 Stopwatch  sw2 = new Stopwatch();

 
Stopwatch sw = new Stopwatch();
 Stopwatch  sw2 = new Stopwatch(); 
  sw.Start();
  Image i1 = ThumbnailLow(img, new Size(100, 100)); 
  sw.Stop();//  
  sw2.Start();
  Image i2 = img.GetThumbnailImage(100, 100, null, IntPtr.Zero); 
  sw2.Stop(); // 正常情况,应该ThumbnailLow 比GetThumbnailImage 快一倍
--------------------编程问答--------------------
引用 19 楼 bebeing 的回复:
Quote: 引用 13 楼 zhoujk 的回复:

每次加载并缩小一个图的思路是正确的。
IO操作没什么好优化的方法,2000*1000 也不是个很大的尺寸,如果太慢, 你换个机机试一下。一秒左右确实慢得太过份了


电脑确实不太先进啊,廉价的办公电脑。

重装或优化一下试试 --------------------编程问答-------------------- 或者换台电脑试 --------------------编程问答--------------------
引用 3 楼 bebeing 的回复:
Quote: 引用 1 楼 lizhi3186575 的回复:

不需要转换的,在PictureBox控件中显示图片,PictureBox控件带有这个功能的,只要需要设置PictureBox1.SizeModel=PictureBoxSizeMode.Zoom就可以了


我在问题中提到了这个方法,但没有使用。
虽然PictureBox可以缩小显示大图片,但PictureBox扔保持原尺寸图片的数据,内存消耗很大。如果显示多个图片,会显示内存不足。
我的做法是先得到一个较小尺寸的图片再给PictureBox显示,这样内存消耗较小。只是得到较小图片的操作很费时间。有没有更好的方法?


你的方法本身就错了,你这种做法相当于,已取到了大图读到内存,再把大图从内存中变成小图,再显示小图,好比拖了裤子放屁,反而更耗内存。还不如直接显示大图。
你要想快,就是写个一工具一次性把大图全缩成小图,然后保存到一个目前录。名称就在大图的名称前面加个m_大图名称.jpg这样。然后每次只要读取小图就行了,等要看大图就再去读对应的大图。 --------------------编程问答--------------------
引用 11 楼 zanfeng 的回复:
如果都是jpg图片。GetThumbnailImage这个方法是挺不错的。
不过不能用.net自带的。
搜一下jpg格式。用jpg格式读出这个挺简单速度也相当快。
我以前帮别人做的一个排版的系统。读取写真照片就用这个方法。
这个方法是对的!顶一个 --------------------编程问答--------------------
引用 25 楼 wyd1520 的回复:
你的方法本身就错了,你这种做法相当于,已取到了大图读到内存,再把大图从内存中变成小图,再显示小图,好比拖了裤子放屁,反而更耗内存。还不如直接显示大图。
你要想快,就是写个一工具一次性把大图全缩成小图,然后保存到一个目前录。名称就在大图的名称前面加个m_大图名称.jpg这样。然后每次只要读取小图就行了,等要看大图就再去读对应的大图。


1.大图读到内存后,得到转换后的小图后,大图占用的内存会被释放掉。
2.大图基本都是动态的和不固定的(不像是某个文件夹下有100个图片基本不变),文件名和数量随时会变化,也基本只会访问一次,所以没有采用保存小图的方法。
--------------------编程问答--------------------
引用 22 楼 yanghl1998 的回复:
 sw 和 sw2 是  Stopwatch ,忘了贴上
Stopwatch sw = new Stopwatch();
 Stopwatch  sw2 = new Stopwatch();

 
Stopwatch sw = new Stopwatch();
 Stopwatch  sw2 = new Stopwatch(); 
  sw.Start();
  Image i1 = ThumbnailLow(img, new Size(100, 100)); 
  sw.Stop();//  
  sw2.Start();
  Image i2 = img.GetThumbnailImage(100, 100, null, IntPtr.Zero); 
  sw2.Stop(); // 正常情况,应该ThumbnailLow 比GetThumbnailImage 快一倍


经过测试,ThumbnailLow方法比img.GetThumbnailImage方法慢一倍时间左右,一个是1500毫秒,一个是780毫秒。
可能的原因是我的所谓小图并不是如100x100的缩略图。假如大图片是8000x6000,我的小图的意思是适合显示器显示的大小,例如1800x1000。 --------------------编程问答--------------------

FileStream ImgStream = File.OpenRead(ImgPath);
Image TempImage = Image.FromStream(ImgStream,false,false);     
 Bitmap Bmp = new Bitmap((int)drawWidth, (int)drawHeight);
            Graphics Myg = Graphics.FromImage(Bmp);
            Myg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
            Myg.DrawImage(TempImage , drawpoint.X, drawpoint.Y, drawWidth, drawHeight);
            return Bmp;


大图显示在picturebox中速度慢的主要原因发生在读取图片文件的时候。比如8000*4000的jpg图片文件大小可能达到10m左右,10m左右文件完全读取到内存中已经花费了几百毫秒,甚至秒级了。
图片缩放所需的时间,其实是非常少的。
所幸,GDI+类库已经考虑到这这点,可以不完全读取图片文件,就可以做缩放。
如上面代码所示,几乎是GDI+能达到的最大速度。如果再要快,楼主需要自己解析图片格式和图片缩放。 --------------------编程问答--------------------
引用 29 楼 yuwenge 的回复:
大图显示在picturebox中速度慢的主要原因发生在读取图片文件的时候。比如8000*4000的jpg图片文件大小可能达到10m左右,10m左右文件完全读取到内存中已经花费了几百毫秒,甚至秒级了。
图片缩放所需的时间,其实是非常少的。
所幸,GDI+类库已经考虑到这这点,可以不完全读取图片文件,就可以做缩放。
如上面代码所示,几乎是GDI+能达到的最大速度。如果再要快,楼主需要自己解析图片格式和图片缩放。


读取文件的确要花些时间,第一次读取一般需要几十毫秒到几百毫秒,再次读取会更快,一般不超过一二百毫秒。
但图片转换确实需要数百毫秒时间。 --------------------编程问答--------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;


namespace ol
{
    public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            LogTraceInfo("A",true);
            bool zoom;
            pictureBox1.Image = GetZoomedImage(@"F:\x\8\a\1.jpg", 3000, 2000, out zoom);            //1.jpg: 8000x6000, 896KB
            LogTraceInfo("B");
        }



        static DateTime _oRefTime = DateTime.Now;

        public static void LogTraceInfo(string info, bool reset = false)
        {
            string file = Application.ExecutablePath + ".log";

            DateTime now = DateTime.Now;
            if (reset) _oRefTime = now;
            TimeSpan ts = now - _oRefTime;

            string text = now.ToString("HH:mm:ss.fff  ") + ts.ToString(@"hh\:mm\:ss\.fff") + "   " + info + Environment.NewLine;

            Debug.Print(text);
            //File.AppendAllText(file, text);
        }


        public static Image GetZoomedImage(string asImageFilename, int width, int height, out bool zoomed)
        {
            Image oNewImage = null;

            LogTraceInfo("ReadAllBytes",true);
            using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(asImageFilename)))
            {
                LogTraceInfo("ReadAllBytes--");

                LogTraceInfo("FromStream",true);
                Image oOriginalImage = Image.FromStream(ms, true, false);
                LogTraceInfo("FromStream--");

                double fWScaleRatio = width / (double)oOriginalImage.Width;
                double fHScaleRatio = height / (double)oOriginalImage.Height;
                double fScaleRatio = Math.Min(fWScaleRatio, fHScaleRatio);
                if (width < 0) fScaleRatio = fHScaleRatio;
                if (height < 0) fScaleRatio = fWScaleRatio;
                int nNewWidth = (int)(oOriginalImage.Width * fScaleRatio);
                int nNewHeight = (int)(oOriginalImage.Height * fScaleRatio);

                if (fScaleRatio < 1.0)
                {
                    Size sz = new Size(nNewWidth, nNewHeight);
                    LogTraceInfo("new Bitmap", true);

                    //Method 1: need 796,828 ms
                    oNewImage = new Bitmap(oOriginalImage, nNewWidth, nNewHeight);

                    //Method 2: need 1546,1578 ms
                    //oNewImage = ThumbnailLow((Bitmap)oOriginalImage, sz);

                    //Method 3: need 812,828 ms
                    //oNewImage = ThumbnailAAAA((Bitmap)oOriginalImage, nNewWidth, nNewHeight);

                    //Method 4: need 765,875 ms
                    //oNewImage = oOriginalImage.GetThumbnailImage(nNewWidth, nNewHeight, new Image.GetThumbnailImageAbort(ImageThumbnailAbortCallback), IntPtr.Zero);

                    LogTraceInfo("Bitmap--");
                    zoomed = true;
                }
                else
                {
                    LogTraceInfo("Clone", true);
                    oNewImage = (Image)oOriginalImage.Clone();
                    LogTraceInfo("Clone--");
                    zoomed = false;
                }

                LogTraceInfo("Dispose", true);
                oOriginalImage.Dispose();
                oOriginalImage = null;
                LogTraceInfo("Dispose--");
            }

            return oNewImage;
        }


        private static bool ImageThumbnailAbortCallback()
        {
            return false;
        }





        private static byte BytesPerPixel(PixelFormat px)
        {
            switch (px)
            {
                case PixelFormat.Format16bppRgb555:
                case PixelFormat.Format16bppRgb565:
                case PixelFormat.Format16bppGrayScale:
                case PixelFormat.Format16bppArgb1555: return 2;
                case PixelFormat.Format24bppRgb: return 3;
                case PixelFormat.Format32bppRgb: return 4;
                case PixelFormat.Format32bppArgb: return 4;
                case PixelFormat.Format32bppPArgb: return 4;
            }
            return 0;
        }

        public static Bitmap ThumbnailLow(Bitmap img, Size sz)
        {
            if (img == null || sz.IsEmpty) return null;
            if (sz.Width > img.Width) sz = new Size(img.Width, sz.Height);
            if (sz.Height > img.Height) sz = new Size(sz.Width, img.Height);
            PixelFormat px = img.PixelFormat;
            PixelFormat pxn = PixelFormat.Format16bppRgb565;
            if (px == PixelFormat.Format32bppArgb || px == PixelFormat.Format32bppPArgb ||
                px == PixelFormat.Format32bppRgb) pxn = PixelFormat.Format24bppRgb;
            byte bytesPerPixel = BytesPerPixel(px), bytesPerPixel2 = BytesPerPixel(pxn);
            Bitmap nueva = new Bitmap(sz.Width, sz.Height, pxn);
            BitmapData bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, px);
            BitmapData bmpData2 = nueva.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadWrite, pxn);
            // 快速转换 
            float inc_djn = img.Width / (float)sz.Width;
            float inc_din = img.Height / (float)sz.Height;
            float din = 0, djn = 0;
            bool _16bits = bytesPerPixel == 2 || bytesPerPixel2 == 2;
            unsafe
            {
                byte* ptr = (byte*)(bmpData.Scan0);
                byte* ptr2 = (byte*)(bmpData2.Scan0);
                int nOffset = bmpData.Stride - (bmpData.Width * bytesPerPixel);
                int nOffset2 = bmpData2.Stride - (bmpData2.Width * bytesPerPixel2);
                int h = bmpData.Height, w = bmpData.Width;
                for (int i = 0; i < h; i++)
                {
                    bool lok = i >= din;
                    djn = 0;
                    for (int j = 0; j < w; j++)
                    {
                        if (lok && j >= djn)
                        {
                            ptr2[0] = ptr[0];
                            ptr2[1] = ptr[1];
                            if (!_16bits) ptr2[2] = ptr[2];
                            ptr2 += bytesPerPixel2;
                            djn += inc_djn;
                        }
                        ptr += bytesPerPixel;
                    }
                    if (lok) { ptr2 += nOffset2; din += inc_din; }
                    ptr += nOffset;
                }
            }
            img.UnlockBits(bmpData);
            nueva.UnlockBits(bmpData2);
            return nueva;
        }



        public static Bitmap ThumbnailAAAA(Bitmap img, int ww, int hh)
        {
            Bitmap Bmp = new Bitmap((int)ww, (int)hh); 
            Graphics Myg = Graphics.FromImage(Bmp); 
            Myg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default; 
            Myg.DrawImage(img, 0, 0, ww, hh); 
            return Bmp;
        }
    }


}


以上是我的测试代码。

1.jpg是一张8000x6000的图片,得到一个不大于3000x2000的图片,显示在PictureBox中。
共测试了4种转换方法,测试两遍,耗时见注释部分。方法1,3,4耗时800毫秒左右,方法2耗时1500毫秒左右。不包括读取文件的耗时。

我的目的就是需要转换尽量快的方法。 --------------------编程问答-------------------- 那所以还是 GetThumbnailImage 最快!  楼主给分吧,大神的GDI+都出来了,还是没这个快,哈哈


要不你就文件流,FileStream  自己夸像素取点构成新缩略图吧,估计没有经过平均插值会很难看
--------------------编程问答-------------------- jpg文件格式本来就比较大,为什么不用png格式? --------------------编程问答--------------------
引用 33 楼 rui_china 的回复:
jpg文件格式本来就比较大,为什么不用png格式?


客户的图片有多种格式,不是我能决定的。 --------------------编程问答-------------------- 全图加载在缩放的主要耗时在JPG图像文件的解码,比如我加载一副8000*4000JPG文件,就耗时了700ms左右,而用线性插值缩放到2000*1000  120ms就可以了。

一般大图的JPG都在内部缓存了缩略图,但是缩略图的大小一般只有160*120大小左右,所以GDI+ 的GetThumbnailImage 并不是直接读取这个数据。  --------------------编程问答-------------------- 仔细的研究了下.net下的GetThumbnailImage函数,结果证明着东西对楼主的要求来说不合适.

http://www.cnblogs.com/Imageshop/archive/2013/06/16/3138623.html --------------------编程问答--------------------
引用 36 楼 laviewpbt 的回复:
仔细的研究了下.net下的GetThumbnailImage函数,结果证明着东西对楼主的要求来说不合适.

http://www.cnblogs.com/Imageshop/archive/2013/06/16/3138623.html


测试过用GetThumbnailImage来获得缩小的图片(比160x120要大很多),显示质量还可以,就是不够快。

我的目标就是,不管什么方法,要足够快。 --------------------编程问答-------------------- 你可以试试多线程处理,并发几个线程同时处理多个图片。 --------------------编程问答-------------------- 原来的方法不变。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,