//下面的代码是把图像压缩为1bpp(1 bit per pixel)后存为tif的代码。
private void SaveToFile(Bitmap newBitmap)
{
     Bitmap img = (Bitmap)newBitmap.Clone();
     if (img.PixelFormat != PixelFormat.Format32bppPArgb)
     {
         Bitmap temp = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppPArgb);
         Graphics g = Graphics.FromImage(temp);
         g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
         img.Dispose();
         g.Dispose();
         img = temp;
      }
            
       //lock the bits of the original bitmap
       BitmapData bmdo = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat);       //and the new 1bpp bitmap
       Bitmap bm = new Bitmap(img.Width, img.Height, PixelFormat.Format1bppIndexed);       BitmapData bmdn = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);       //for diagnostics
       DateTime dt = DateTime.Now;       //scan through the pixels Y by X
       int x, y;
       for (y = 0; y < img.Height; y++)
       {
           for (x = 0; x < img.Width; x++)
           {
              //generate the address of the colour pixel
              int index = y * bmdo.Stride + (x * 4);
              //check its brightness
              if (Color.FromArgb(Marshal.ReadByte(bmdo.Scan0, index + 2),
                                 Marshal.ReadByte(bmdo.Scan0, index + 1),
                                 Marshal.ReadByte(bmdo.Scan0, index)).GetBrightness() > 0.5f)
                        this.SetIndexedPixel(x, y, bmdn, true); //set it if its bright.
             }
        }        //tidy up
        bm.UnlockBits(bmdn);
        img.UnlockBits(bmdo);        ImageCodecInfo icf = GetEncoderInfo("image/tiff");
        System.Drawing.Imaging.Encoder myEncoder;
        myEncoder = System.Drawing.Imaging.Encoder.Compression;
        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, (long)EncoderValue.CompressionCCITT4);
        EncoderParameters myEncoderParameters;
        myEncoderParameters = new EncoderParameters(1);
        myEncoderParameters.Param[0] = myEncoderParameter;        bm.Save("c:\\new.tif", icf, myEncoderParameters); //问题是这里能不能不存为文件,直接写进数据库?
}// GetEncoderInfo()方法
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
            int j;
            ImageCodecInfo[] encoders;            encoders = ImageCodecInfo.GetImageDecoders();
            for (j = 0; j < encoders.Length; j++)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
}bm.Save("c:\\new.tif", icf, myEncoderParameters); 是把彩色图压缩成黑白图后存为new.tif的代码。那么能不能不经过写磁盘的操作,既能压缩为CCITT4黑白图格式,又能在内存中直接把它存到数据库某个BLOB或IMAGE这样的字段里?

解决方案 »

  1.   

    既然已经存为文件了,那么数据库并不关心存的文件格式是什么,只要是byte流,都可以存进去。
    参看
    http://blog.csdn.net/knight94/archive/2006/03/24/637800.aspx
      

  2.   

    to: Knight94(愚翁)目的是不经过存为文件的过程。直接把图写进数据库。
    bm.Save("c:\\new.tif", icf, myEncoderParameters); 
    这里的c:\\new.tif可不可以是MemoryStream?看文档应该可以。再把MemoryStream转换成byte[]后存?
      

  3.   

    to 目的是不经过存为文件的过程。直接把图写进数据库。
    bm.Save("c:\\new.tif", icf, myEncoderParameters);
    这里的c:\\new.tif可不可以是MemoryStream?看文档应该可以。
    再把MemoryStream转换成byte[]后存?由于你的图形需要编码转换,因此你先进行保存,然后再去读,要好一些。
      

  4.   

    to 这里的c:\\new.tif可不可以是MemoryStream?看文档应该可以这里建议不要用MemoryStream,主要你不知道要给MemoryStream分多大的空间
      

  5.   

    to: Knight94(愚翁) 把图片转换成CCITT4,也就是黑白图以后。System.IO.MemoryStream ms = new System.IO.MemoryStream();
    bm.Save(ms, icf, myEncoderParameters);然后, byte[] byt = ms.ToArray();
    再把byt写进数据库和存到文件后再写进数据库有什么区别呢?
      

  6.   

    to: Knight94(愚翁)这里主要还是为了效率问题啊,因为要处理的数据量接近100万条,为了能节省时间,我希望程序能减少磁盘操作。
      

  7.   

    to: littlegang(Gang) 是把数据库中的图片取出来后进行处理后用TIF CCITT4(可以看作是黑白图)格式压缩后存回数据库的应用。我的目的是尽可能节省处理的时间。
      

  8.   

    to
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    bm.Save(ms, icf, myEncoderParameters);
    byte[] byt = ms.ToArray();这样是没有问题的。