2012-06-11 70 views
4

这可能是不可能的,或者说,不是很流行,但我想知道如何创建图像的数据文件,实际上会压缩它们?假设我总共有200MB的图像文件,是否有一些系统可以将它们存储在一个文件中,这会将它们压缩为150MB的总大小? (只是示例数字,比例不重要)。可压缩图像库吗?

我知道我可以使用Base64对图像进行编码,然后将它们存储在SQLite数据库中,但我读到以其编码形式存储图像实际上导致比原始图像文件本身的尺寸稍大。

我也在考虑一个ZIP文件,但我不确定它是否可以用作'库'这样的文件?

如果像这样的东西不存在作为预定义的类,有人可以让我走在正确的轨道上吗?

这是什么,我有点找一个模拟:

class ImageLibrary { 
    //this is where the code would go for the library? 
} 

class MyProgram{ 
    public MyProgram() 
    { 
    ImageLibrary library = new ImageLibrary(); 
    library.Add(<Image object here, with an ID of sorts>); 
    library.Add(<Another image object here, also with an ID>); 
    Load += new FormLoadEventHandler(MyProgram_Load); 
    } 

    void MyProgram_Load(object sender, EventArgs e) 
    { 
    PictureBox.Image = library.Get(<image id here>); 
    } 
} 

我希望这是可能的。否则,我会忍受一个稍大的文件大小并Base64编码它们。但是,因为目前我有将近500张图像需要存储,因此保存的kB是获得的kB。 :)另外,请不要判断我的代码示例的质量,它只是一个模拟,我把它从袖口写下来。

干杯,谢谢你提前。

+0

base64的大小约为1.33倍,但我非常肯定SQLite支持BLOB,所以编码它们是没有必要的。 – Thomas

+0

@Thomas很高兴知道,我没有想到这一点。因此,我知道它至少与图像大小相同,并且由于存储在数据库中的附加细节会增加每个图像的kb。有没有什么办法在储存前压缩这些图像? –

+1

@Spiritfire:通常你不会通过压缩优化过的jpg/png等来减小尺寸(有时甚至会增加!)。只要确保在保存之前对它们进行了优化。 –

回答

3

如果将图像保存为二进制文件将有助于这是我使用将它们转换为二进制文件,然后保存到SQLite的代码:

public byte[] ImageToByte(Image image, System.Drawing.Imaging.ImageFormat format){ 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      // Convert Image to byte[] 
      image.Save(ms, format); 
      byte[] imageBytes = ms.ToArray(); 
      return imageBytes; 
     } 
    } 
    public Image ByteToImage(byte[] imageBytes) 
    { 
     // Convert byte[] to Image 
     MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length); 
     ms.Write(imageBytes, 0, imageBytes.Length); 
     Image image = new Bitmap(ms); 
     return image; 
    } 

然后保存二进制:

void SaveImage(byte[] image){ 
     string conStringDatosUsuarios = @" Data Source = \Program Files\GPS___CAM\Data\DatosUsuarios.s3db ";    
     SQLiteConnection con = new SQLiteConnection(conStringDatosUsuarios); 
     SQLiteCommand cmd = con.CreateCommand(); 
     cmd.CommandText = String.Format("INSERT INTO Users (Foto) VALUES (@0);"); 
     SQLiteParameter p = new SQLiteParameter("@0", System.Data.DbType.Binary); 
     p.Value = image; 
     cmd.Parameters.Add(p);    
     con.Open(); 
     try 
     { 
      cmd.ExecuteNonQuery(); 
     } 
     catch (Exception exc1) 
     { 
      MessageBox.Show(exc1.Message); 
     } 
     con.Close(); 
    } 

希望它可以帮助

编辑至于你问,我与负载图像代码更新: (以字节转换为IMAG Ë您必须使用ByteToImage功能)

void LoadImage(string tag){ 
     string query = "SELECT Foto FROM Users;"; 
     string conString = @" conection to your database "; 
     SQLiteConnection con = new SQLiteConnection(conString); 
     SQLiteCommand cmd = new SQLiteCommand(query, con);    
     con.Open(); 
     try 
     { 
      SQLiteDataReader rdr = cmd.ExecuteReader(); 
      try 
      { 
       while (rdr.Read()) 
       { 
        pictureBox1.Image = ByteToImage((System.Byte[])rdr[0]); 
       } 
      } 
      catch (Exception exc) { MessageBox.Show(exc.Message); } 
     } 
     catch (Exception ex) { MessageBox.Show(ex.Message); } 
     con.Close(); 
    } 

EDIT 2试试这个,看看哪些类型的数据是你想负荷:

System.Type checkType = rdr[0].GetType(); 
pictureBox1.Image = ByteToImage((System.Byte[])rdr[0]); 

添加的第一行代码,并把一该行中的断点。检查checkType的类型。可能它不是二元的。让我知道结果来帮助你。

+0

这可能是有希望的。你知道它对文件大小有什么影响吗?例如。更小,更大,相等? –

+0

@Spiritfyre我使用此代码将我的图像保存到我的分贝,并且尺寸与原始尺寸相同。我试图用base64保存它们,但它变成了更大的文件。到目前为止,这是最好的,我可以实现保存我的图像 –

+0

非常好,我使用这个,它的工作非常好。可悲的是,我没有图像压缩,但至少它是我寻找的90%。额外的好处是,它在'SQLite'数据库中,使我的工作非常简单。非常感谢:) –

1

看看这篇文章:http://msdn.microsoft.com/en-us/library/aa479502.aspx

我希望它能帮助。从ZIP访问文件的想法。这不是可以立即使用的解决方案,而是一个很好的概念解释。

+0

这看起来似乎值得研究..但是在我深入研究之前,你知道它是否支持索引吗?比如,在每个文件中加上一个字符串来索引它,就像数据库那样? –