Сохраняемая библиотека изображений со сжатием?

Это может быть невозможным, или, скорее, не очень популярным, но мне было интересно, как я могу создать файл данных для изображений, который бы фактически сжимал их? Скажем, у меня было всего 200 МБ файлов изображений, есть ли какая-нибудь система, которую я могу использовать для хранения их в одном файле, которая бы сжимала их до общего размера около 150 МБ? (Просто пример чисел, отношения не важны).

Я знаю, что могу кодировать изображения с 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 изображений, которые я хочу сохранить, сохраненный килобайт - это заработанный килобайт.:) Также, пожалуйста, не судите о качестве моего примера кода, это всего лишь макет, и я списал его с руки.

Ура, и спасибо заранее.

2 ответа

Решение

Если сохранение ваших изображений в виде двоичных файлов поможет, это код, который я использую для преобразования их в двоичный файл, а затем сохранить в 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();
    }

Надеюсь, поможет

РЕДАКТИРОВАТЬ Как вы просили, я обновляюсь с кодом загрузки изображения: (чтобы преобразовать байт в изображение, вы должны использовать 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();
    }

РЕДАКТИРОВАТЬ 2 Попробуйте это, чтобы увидеть, какой тип данных вы пытаетесь загрузить:

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

добавьте первую строку в ваш код и поставьте точку останова в этой строке. Проверьте тип checkType. Вероятно, это не бинарный. Дайте мне знать результат, чтобы помочь вам.

Проверьте эту статью: http://msdn.microsoft.com/en-us/library/aa479502.aspx

Я надеюсь, что это помогает. Идея для доступа к файлам из ZIP. Это не готовое решение, а хорошее объяснение концепции.

Другие вопросы по тегам