Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сжатие, файлов 
:(
    Опции темы
Лена
Дата 21.11.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Если открыть в профессиональном графическом редакторе (например, в CorelPHOTO-PAINT или Adobe Photoshop) фотографию JPG созданную цифровым фотоаппаратом размером 1.5 Мгб и сохранить ее (например, с установками по умолчанию), то получим файл размером 600-800 Кб и он будет хорошего качества. Можно ли средствами C++ Builder (или сторонними компонентами) реализовать сжатие jpg файлов?

PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Здрасте, приехали smile

TJPEGImage::Compess 


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 21.11.2006, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



 smile 
Примерно так?:
Код

if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
         {
            auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
            jpeg->LoadFromFile(fileName);
            bitmap->Assign(jpeg.get());
            jpeg->CompressionQuality = 80;
            jpeg->Compress();
         }

PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Угу

Добавлено @ 16:16 
Опс...  Не так.
Что же Вы делаете? Сначала jpeg в bmp преобразуете, а потом   jpeg  сжимаете
Надо сначала сжать, а потом уж преобразовать
Код

if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
         {
            auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
            jpeg->LoadFromFile(fileName);
            jpeg->CompressionQuality = 80;
            jpeg->Compress();
            bitmap->Assign(jpeg.get());

         }




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 21.11.2006, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Понятно.
Что может означать эта ошибка после добавления этих двух строк? В файле jpeg.hpp цифры 41 не нашла.  smile 


Исключение на строке:  bitmap->Assign(jpeg.get());

Это сообщение отредактировал(а) Лена - 21.11.2006, 16:47

Присоединённый файл ( Кол-во скачиваний: 20 )
Присоединённый файл  1.gif 5,60 Kb
PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Попробуйте добавить
Код

jpeg->Compress();
jpeg->DIBNeeded();
bitmap->Assign(jpeg.get());




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 21.11.2006, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  21.11.2006,  17:10 Найти цитируемый пост)
jpeg->DIBNeeded();


Та же ошибка осталась. Не хочет jpg переделываться в bmp.  smile

Добавлено @ 17:20 
Вот так сработало:
jpeg->DIBNeeded();
jpeg->CompressionQuality = 80;
или даже так:
jpeg->CompressionQuality = 10; //все равно 9 МгБ
jpeg->Compress();
Однако я сделала сохранение на диск для проверки. В результате получила размер фотографии 9 Мгб, исходная была 1.8 Мгб.  smile 

Это сообщение отредактировал(а) Лена - 21.11.2006, 17:28
PM MAIL   Вверх
Лена
Дата 21.11.2006, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



В качестве эксперимента сделала черно-белую:
Код

     if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
         {
            auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
            jpeg->LoadFromFile(fileName);
            jpeg->Grayscale = true;
            jpeg->DIBNeeded();
            jpeg->CompressionQuality = 10;
            jpeg->Compress();

            bitmap->Assign(jpeg.get());

         }
           else
           {
               bitmap->LoadFromFile(fileName);
           }
      bitmap->SaveToStream(stream.get());
      bitmap->SaveToFile("1234.jpg");
//*************


Получила 3МгБ. Очевидно не удасться записывать в базу зажатые jpg потому что они разжимаются когда превращаются в битмап.  smile 
PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Скорее всего так и есть. Есть выход  - хранить все в формате JPEG. Только сохранять и доставать придется ручками


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 21.11.2006, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  21.11.2006,  17:58 Найти цитируемый пост)
Есть выход  - хранить все в формате JPEG.


Не поняла. Хранить картинки не в базе? Ведь в базу JPEG не записываются?

PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



В БД можно записать все что угодно smile и прочитатать все что угодно, если делать ручками
Примерный план следующий 
1. Yбрать TGraphicField, вместо него установить TBlobField
2. Изменить код
Код

try{

  TWaitCursor cursor(crSQLWait);
  AnsiString  fileName = ThumbnailList1->Thumbnails->Items[ThumbnailList1->ItemIndex]->Filename;
  auto_ptr<TMemoryStream> stream(new TMemoryStream());
  auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 
  AnsiString EXE = ExtractFileExt(fileName);
  if( EXE ==".bmp" || EXE ==".BMP" )
  {
        auto_ptr<Graphics::TBitmap> bitmap(new Graphics::TBitmap()); 
        bitmap->LoadFromFile(fileName);
        jpeg->Assign(bitmap.get());
  }
  jpeg->CompressionQuality = 80;
  jpeg->SaveToStream(stream.get());
  stream->Position = 0;
  DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
  DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
  DataModule2->ADOQueryPhoto->ExecSQL();
 }
 catch(...)
       {
        ShowMessage("Не удалось отправить фотографию в базу");
       } 



3. Заменить  DBImage на Image
4. Вычитывать картинку из БД примерно так
Код

  auto_ptr<TMemoryStream> stream(new TMemoryStream());
  auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
  DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 Image1->Picture->Bitmap->Assign(jpeg.get());







--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 21.11.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Cпасибо попробую переделать. Согласно последней вводной, нужна поддрежка только JPG (bmp не будет).  smile 

PM MAIL   Вверх
Лена
Дата 21.11.2006, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Ошибка тут:
DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->SaveToStream(stream.get());

[C++ Error] MDataBase.cpp(1124): E2316 'SaveToStream' is not a member of 'TParameter'
PM MAIL   Вверх
Vyacheslav
Дата 21.11.2006, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(Лена @  21.11.2006,  19:06 Найти цитируемый пост)
DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->SaveToStream(stream.get());

Ну естественно. Надеюсь Вы уже исправли smile на
Код

DataModule2->ADOQueryPhoto->FieldByName("photo")->SaveToStream(stream.get());


И насчет ADOQueryPhoto не уверен. Вы  уж поставте тот, у которого запрос в  select photo from photos where id = :id. ADOQueryX кажется ?



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  21.11.2006,  20:05 Найти цитируемый пост)
Вы уже исправли 


Я пробывала оба варианта. Если так:
Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryX->FieldByName("photo")->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();

то тоже ошибка:
[C++ Error] MDataBase.cpp(1127): E2316 'SaveToStream' is not a member of 'TField'
 smile 
PM MAIL   Вверх
Coala
Дата 22.11.2006, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 4.5.2006
Где: Москва

Репутация: нет
Всего: 0



Код

// FDM->QrDatImg - это TADOQuery из модуля данных
__private :
   TMemoryStream *stm;
   TGPEGImage *jpg;
// где-нибудь в FormCreate
   stm = new TMemoryStream();
   jpg = new TGPEGImage();
//---------------------------------------------------------------------------
// Запись из файла в БЛОБ-поле
void __fastcall TFMain::AddImage() {
  if (!OPD1->Execute()) {
    FDM->QrDatImg->Cancel();
    return;
  }
  Repaint();
  Screen->Cursor = crHourGlass;
  stm->Clear();
  stm->LoadFromFile(OPD1->FileName);
  ((TBlobField*)FDM->QrDatImg->FieldByName("IMAGE"))->LoadFromStream(stm);
  FDM->QrDatImg->Post();
  ShowImage();
  Screen->Cursor = crDefault;
}
//-----------------------------------------------------------------------------------------------
// чтение из поля и загрузка в TImage, лежащеи на СкроллБоксе
void __fastcall TFMain::ShowImage() {
  stm->Clear();
  TStream *bs = FDM->QrDatImg->CreateBlobStream(FDM->QrDatImg->FieldByName("IMAGE"), bmRead);
  if ((!stm) || (stm->Size == 0)) {
     return;
  }
  Image1->Visible = true;
  stm->Position = 0;
  jpg->LoadFromStream(stm);
  ScrollBox1->HorzScrollBar->Range = jpg->Width;
  ScrollBox1->VertScrollBar->Range = jpg->Height;
  Image1->Picture->Assign((TPersistent*)jpg);
}


Это сообщение отредактировал(а) Coala - 22.11.2006, 11:28
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Лена. Крутимся по кругу. 
Должно быть не TField, а  TBlobField?
У Вас он действительно TField? 
В конце концов я набираю по памяти. Немного фантазии и
можно так
Код

DataModule2->ADOQueryXphoto->SaveToStream(stream.get());

или так
Код

((TBlobField*)DataModule2->ADOQueryX->FieldByName("photo"))->SaveToStream(stream.get());


У меня же Вашего кода нет, а у Вас есть smile Вам должно быть проще.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Теперь понятно. Надо обращаться не посредственно к имени поля ADOQueryXphoto.  smile 

Новый код отправки вызвает ошибку №1
Код

try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      auto_ptr<TMemoryStream> stream(new TMemoryStream());
      auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
      jpeg->LoadFromFile(fileName);
      jpeg->CompressionQuality = 80;
      jpeg->Compress();
      jpeg->SaveToStream(stream.get());
      stream->Position = 0;
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
      DataModule2->ADOQueryPhoto->ExecSQL();
     }
 catch(...)
       {
        ShowMessage("Íå óäàëîñü îòïðàâèòü ôîòîãðàôèþ â áàçó");
       }

При добавлении строки jpeg->DIBNeeded(); в код выше получаю ошибку N2

Код получение информации из бызы вызвает ошибку N3:
Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();



Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  1.gif 22,89 Kb
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



1)Тип параметра img?
2)  jpeg->DIBNeeded() ? Зачем он здесь
3) Пустая запись?


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  22.11.2006,  12:21 Найти цитируемый пост)
Тип параметра img?


Тип параметра не меняла ftBlob


Цитата(Vyacheslav @  22.11.2006,  12:21 Найти цитируемый пост)
jpeg->DIBNeeded() ? Зачем он здесь


Его нет, просто проверила.

Цитата(Vyacheslav @  22.11.2006,  12:21 Найти цитируемый пост)
3) Пустая запись? 


Сначала старым рабочим кодом занесла jpg файл в базу:
Код

try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      auto_ptr<TMemoryStream> stream(new TMemoryStream());
      auto_ptr<Graphics::TBitmap> bitmap(new Graphics::TBitmap());
      AnsiString EXE = ExtractFileExt(fileName);
       if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
         {
            auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
            jpeg->LoadFromFile(fileName);

            bitmap->Assign(jpeg.get());

         }
           else
           {
               bitmap->LoadFromFile(fileName);
           }
      bitmap->SaveToStream(stream.get());
      //bitmap->SaveToFile("1234.jpg");
      stream->Position = 0;
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
      DataModule2->ADOQueryPhoto->ExecSQL();
    }
   catch(...)
       {
        ShowMessage("Íå óäàëîñü îòïðàâèòü ôîòîãðàôèþ â áàçó");
       }


Затем попробывала прочитать. Ошибка №3.
Аналогичная ошибка при попытке прочитать пустое поле из базы.

PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Ваш код чтения из БД целиком давайте.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  22.11.2006,  12:51 Найти цитируемый пост)
Ваш код чтения из БД 


Сейчас такой:
Код

//нажала на кнопку
 FormProsmotrFoto->Top = Form1->Top;
 FormProsmotrFoto->Left = Form1->Left  + Form1->Width - FormProsmotrFoto->Width;
 FormProsmotrFoto->Label1->Caption = DataModule2->ClientDataSetVis->FieldByName("lastname")->AsString +
        " " + DataModule2->ClientDataSetVis->FieldByName("firstname")->AsString +
                " " + DataModule2->ClientDataSetVis->FieldByName("patronymic")->AsString +
                        " " + DataModule2->ClientDataSetVis->FieldByName("post")->AsString;


auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();



Раньше был такой:
Код

 FormProsmotrFoto->Top = Form1->Top;
 FormProsmotrFoto->Left = Form1->Left  + Form1->Width - FormProsmotrFoto->Width;
 FormProsmotrFoto->Label1->Caption = DataModule2->ClientDataSetVis->FieldByName("lastname")->AsString +
        " " + DataModule2->ClientDataSetVis->FieldByName("firstname")->AsString +
                " " + DataModule2->ClientDataSetVis->FieldByName("patronymic")->AsString +
                        " " + DataModule2->ClientDataSetVis->FieldByName("post")->AsString;


          TWaitCursor cursor(crSQLWait);
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->Active = true;


PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



А где,в текущем коде запрос в БД? Он же никуда не делся и должен был перкочевать из предыдущей версии. Вы дожны были просто добавить дополнительный код
Код

//нажала на кнопку
 FormProsmotrFoto->Top = Form1->Top;
 FormProsmotrFoto->Left = Form1->Left  + Form1->Width - FormProsmotrFoto->Width;
 FormProsmotrFoto->Label1->Caption = DataModule2->ClientDataSetVis->FieldByName("lastname")->AsString +
        " " + DataModule2->ClientDataSetVis->FieldByName("firstname")->AsString +
                " " + DataModule2->ClientDataSetVis->FieldByName("patronymic")->AsString +
                        " " + DataModule2->ClientDataSetVis->FieldByName("post")->AsString;


          TWaitCursor cursor(crSQLWait);
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->Active = true;


auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphоto>SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();


Естественно Вы вытаскиваете пустую запись


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Заношу в базу старым кодом:
Код

try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      auto_ptr<TMemoryStream> stream(new TMemoryStream());
      auto_ptr<Graphics::TBitmap> bitmap(new Graphics::TBitmap());
      AnsiString EXE = ExtractFileExt(fileName);
       if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
         {
            auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
            jpeg->LoadFromFile(fileName);

            bitmap->Assign(jpeg.get());

         }
           else
           {
               bitmap->LoadFromFile(fileName);
           }
      bitmap->SaveToStream(stream.get());
      //bitmap->SaveToFile("1234.jpg");
      stream->Position = 0;
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
      DataModule2->ADOQueryPhoto->ExecSQL();
    }
   catch(...)
       {
        ShowMessage("Íå óäàëîñü îòïðàâèòü ôîòîãðàôèþ â áàçó");
       }


Читаю новым кодом: 
Код


          TWaitCursor cursor(crSQLWait);
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->Active = true;




 auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();


Ошибка на рисунке.

Попытка занести новым кодом, ругается попрежнему на параметр.
Код

try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      auto_ptr<TMemoryStream> stream(new TMemoryStream());
      auto_ptr<TJPEGImage> jpeg (new TJPEGImage());

      jpeg->LoadFromFile(fileName);
      jpeg->CompressionQuality = 80;
      jpeg->Compress();
      jpeg->SaveToStream(stream.get());
      stream->Position = 0;
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
      DataModule2->ADOQueryPhoto->ExecSQL();
     }
 catch(...)
       {
        ShowMessage("Íå óäàëîñü îòïðàâèòü ôîòîãðàôèþ â áàçó");
       }




Это сообщение отредактировал(а) Лена - 22.11.2006, 13:22

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  1.gif 5,78 Kb
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Лена. Читать с помощью нового кода информацию, записанную старым кодом бессмысленно. У Вас старым кодом записывается формат BMP

Добавлено @ 13:33 
Уберите
jpeg->Compress();



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Vyacheslav @  22.11.2006,  13:32 Найти цитируемый пост)
Уберите
jpeg->Compress();


Все заработало, только мы ничего не выиграли.  smile  
Сохранила картинку полученную в Image1 на диск. Был размер 1.8 стал 9 МГб. Как у Тома Круза: "Миссия не выполнима".  smile 
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Ответ не верный smile
Дайте код как проверяли 
Надеюсь, что так (правильно)
Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 jpeg->SaveToFile("test.jpg");

или так (неправильно)
Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
FormProsmotrFoto->Image1->Picture->SaveToFile("test.bmp")
        



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 jpeg->SaveToFile("test.jpg");


Полученная таким образом картинка, точно соотвествует исходной по размеру и равняется 1.8 МгБ. Видимо Compress(); нужен, но он портит параметр.  smile 
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Ага. Значит проверяли изначально все таки неправильно. smile
Ну судя по хелпу 
Цитата

typedef Shortint TJPEGQualityRange; 
__property TJPEGQualityRange CompressionQuality = {read=FQuality, write=FQuality, nodefault};

Description

Use CompressionQuality to set the compression quality of the JPEG image when writing out a jpeg image. Higher compression results in a poorer picture quality, but a smaller file size. This property is not used for reading in files. 

Этого должно быть достаточно
Код

jpeg->CompressionQuality = 80;

без  вызова Compress;

Добавлено @ 14:40 
Прочитав вниматльно smile help я понял, что Compress используется для сжатия после присвоения BMP -> JPEG типа
Код

jpeg->Assign(bitmap);
jpeg->Compress();

а CompressionQuality используется при сохранении jpeg
Код

jpeg->CompressionQuality = 50;
jpeg->SaveToStream( stream ); //jpeg->SaveToFile("test.jpg");




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Пока писала сообщения получила новое разъяснения по Compress от вас.  smile 


Хочу отметить, что новый код загрузки:
Код

try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      auto_ptr<TMemoryStream> stream(new TMemoryStream());
      auto_ptr<TJPEGImage> jpeg (new TJPEGImage());

      jpeg->LoadFromFile(fileName);
      jpeg->CompressionQuality = 80;
      //jpeg->Compress();
      jpeg->SaveToStream(stream.get());
      stream->Position = 0;
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
      DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
      DataModule2->ADOQueryPhoto->ExecSQL();
     }
 catch(...)
       {
        ShowMessage("Íå óäàëîñü îòïðàâèòü ôîòîãðàôèþ â áàçó");
       }

мне кажется, работает надежнее. У меня была одна картинка jpeg размеров всего 700 Кб, так мой прошлый код загрузки выдавал исключение (переполнение буфера и прочее). Этот код загрузил эту картинку в базу нормально.  smile 

Раньше, если в базе не было картинки, DBImage был пустой, теперь загрузка в такой ситуации вызывает исключение. Как грамотнее его обработать? 


Похоже, CompressionQuality не работает. Пробовала так: CompressionQuality=10 получила тот же размер. Может для эксперимента перед отправкой сохранять файл с Compress(); на диск, а потом пробовать отправить его в базу, а после отправки временный файл удалять или все это ерунда?



Это сообщение отредактировал(а) Лена - 22.11.2006, 14:44
PM MAIL   Вверх
Лена
Дата 22.11.2006, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Может так обработать пустую картинку?
Код

auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 if(!stream->Size) return;
 jpeg->LoadFromStream(stream.get());
  FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
 FormProsmotrFoto->ShowModal();

PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(Лена @  22.11.2006,  14:43 Найти цитируемый пост)
Похоже, CompressionQuality не работает. Пробовала так: CompressionQuality=10 получила тот же размер. Может для эксперимента перед отправкой сохранять файл с Compress(); на диск, а потом пробовать отправить его в базу, а после отправки временный файл удалять или все это ерунда?

Кстати , мне пришла такая же идея. Во всяком случае можно проверить изначальный размер  и после сжатия но до отсылки в БД

Цитата(Лена @  22.11.2006,  14:43 Найти цитируемый пост)
Раньше, если в базе не было картинки, DBImage был пустой, теперь загрузка в такой ситуации вызывает исключение. Как грамотнее его обработать? 

Код

if( DataModule2->ADOQueryXphoto->IsNull)
{
   FormProsmotrFoto->Image1->Picture->Bitmap->Assign(NULL) ;
   return;
}
auto_ptr<TMemoryStream> stream(new TMemoryStream());
 auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
 DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
 stream->Position = 0;
 jpeg->LoadFromStream(stream.get());
 FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
        



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Не знаю как будет дальше, но сейчас весь код очень хорошо работает и устойчиво:
Отправка:
Код

void __fastcall TFormFoto::Button1Click(TObject *Sender)
{
//отправить фото в базу
if (AdvPicture1->Picture->Empty==true)
{
  ShowMessage("Необходимо выбрать фотографию");
  return;
}

  try{

      TWaitCursor cursor(crSQLWait);
      AnsiString  fileName = PathFolder;
      AnsiString EXE = ExtractFileExt(fileName);
       if( EXE ==".jpg" || EXE ==".jpeg" || EXE ==".JPG" || EXE ==".JPEG")
          {
          auto_ptr<TMemoryStream> stream(new TMemoryStream());
          auto_ptr<TJPEGImage> jpeg (new TJPEGImage());

          jpeg->LoadFromFile(fileName);
          jpeg->CompressionQuality = 10;
          //jpeg->Compress();
          jpeg->SaveToStream(stream.get());
          stream->Position = 0;
          DataModule2->ADOQueryPhoto->Parameters->ParamByName("img")->LoadFromStream(stream.get(), ftBlob);
          DataModule2->ADOQueryPhoto->Parameters->ParamByName("id")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryPhoto->ExecSQL();
          }
          else{

               ShowMessage("Не правильное расширение файла фотографии");
               return;
               }
     }
     catch(...)
           {
            ShowMessage("Не удалось отправить фотографию в базу");
           }

}


Получение фотографии:
Код

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
 try{
 FormProsmotrFoto->Top = Form1->Top;
 FormProsmotrFoto->Left = Form1->Left  + Form1->Width - FormProsmotrFoto->Width;
 FormProsmotrFoto->Label1->Caption = DataModule2->ClientDataSetVis->FieldByName("lastname")->AsString +
        " " + DataModule2->ClientDataSetVis->FieldByName("firstname")->AsString +
                " " + DataModule2->ClientDataSetVis->FieldByName("patronymic")->AsString +
                        " " + DataModule2->ClientDataSetVis->FieldByName("post")->AsString;


          TWaitCursor cursor(crSQLWait);
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->Active = true;


 if( DataModule2->ADOQueryXphoto->IsNull)
   {
   FormProsmotrFoto->Image1->Picture->Bitmap->Assign(NULL) ;
   ShowMessage(FormProsmotrFoto->Label1->Caption + " не имеет фотографии в базе");
   return;
   }
     auto_ptr<TMemoryStream> stream(new TMemoryStream());
     auto_ptr<TJPEGImage> jpeg (new TJPEGImage());
     DataModule2->ADOQueryXphoto->SaveToStream(stream.get());
     stream->Position = 0;
     jpeg->LoadFromStream(stream.get());
     FormProsmotrFoto->Image1->Picture->Bitmap->Assign(jpeg.get());
     FormProsmotrFoto->ShowModal();
 }
  catch(...)
   {
    ShowMessage("Не удалось загрузить фотографию");
   }
}


Удаление фотографии:
Код

void __fastcall TFormProsmotrFoto::ButtonDropFotoClick(TObject *Sender)
{

          try{
          TWaitCursor cursor(crSQLWait);
          //удаление
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->SQL->Clear();
          DataModule2->ADOQueryX->SQL->Add("UPDATE photos SET photo=NULL WHERE id =:cur");
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->ExecSQL();

          //возвращение запроса
          DataModule2->ADOQueryX->Active = false;
          DataModule2->ADOQueryX->SQL->Clear();
          DataModule2->ADOQueryX->SQL->Add("select photo from photos where id=:cur");
          DataModule2->ADOQueryX->Parameters->ParamByName("cur")->Value = DataModule2->ClientDataSetVisid->AsInteger;
          DataModule2->ADOQueryX->Active = true;
          FormProsmotrFoto->Image1->Picture->Bitmap->Assign(NULL) ;
           }
           catch(...)
              {
               ShowMessage("Не удалось удалить фотографию");
              }

}


Вообщем УРА!  smile 



Это сообщение отредактировал(а) Лена - 22.11.2006, 15:59
PM MAIL   Вверх
Vyacheslav
Дата 22.11.2006, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Замечание.
За такие
Код

 catch(...)
   {
    ShowMessage("Не удалось загрузить фотографию");
   }

я своих подчиненных расстреливаю. Чтоб не  мучались. smile
Правильно было бы сделать что-то вроде этого
Код

 catch(Exception* ex)
   {
    //записать в лог-файл содержимой оригинального сообщения
    WriteToLog(ex->Message);
    ShowMessage("Не удалось загрузить фотографию");
   }

WriteToLog - это конечно своя функция.
А вообще у меня был свой диалоговое окно, где при подобной ситуации высветилось сообщение "Не удалось загрузить фотографию". Это там, где на рисунке сейчас стоит по умолчанию "Программа выполнила недопустимую операцию" А если пользователь нажмет на кнопку, то диалоговое окно распахнется и  там будет подробная информация, которая автоматом запишется в лог. По этой информации можно достаточно быстро локализовать и пофиксить баг, не приставая к пользователю с вопросами типа :"А ну-ка покажи, что ты сделал, чтобы получить такую ситуацию"

Добавлено @ 16:36 
Ну и вся обработка ошибок примерно выполнялась следующим образом
Код

void __fastcall TMainDataModule::ApplicationEventsException(
      TObject *a_Sender, Exception *a_Exc)
{
    // Если это клиентское исключение, то просто выдаем сообщение..
     if (EipException* Exc = dynamic_cast<EipException*>(a_Exc))
        {
            Exc->Show();
            return;
        }
        // Если это серьезная ошибка
        std::auto_ptr<TErrorDialog> Dlg(new TErrorDialog(this, a_Exc,a_Sender));
        Dlg->ShowModal();
        // если ошибка произошла при входе в систему,
        // прекращаем работу
        if (m_Logining)
            Application->Terminate();
 }



Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  except.jpg 23,39 Kb


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Лена
Дата 22.11.2006, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Да, файл лог обязательно добавлю.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1203 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.