C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Cжатие, файлов
Лена
Отправлено: 21.11.2006, 15:42


Мастер участка

Группа: Участник
Сообщений: 501



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

olegenty
Отправлено: 21.11.2006, 16:13


Ветеран

Группа: Модератор
Сообщений: 2412



можно, воспользуйся указанным тебе мной пакетом, он это умеет.
Лена
Отправлено: 21.11.2006, 16:17


Мастер участка

Группа: Участник
Сообщений: 501



Вот еще нашла у Архангельского в книге:
#include Jpeg.hpp

TJPEGImage *jpg = new TJPEGImage()


//перед сохранением
jpeg->CompressionQuality = 80;//1-100
jpeg->Compress();

Отредактировано Лена — 21.11.2006, 16:18
olegenty
Отправлено: 21.11.2006, 17:15


Ветеран

Группа: Модератор
Сообщений: 2412



там примерно аналогично, но конвертация проще: есть куча методов типа
SaveAsJpeg
SaveAsBmp
SaveAs...
...
Grigoriy
Отправлено: 21.11.2006, 22:48


Мастер участка

Группа: Участник
Сообщений: 381



Работает под XP и выше.
Понимает исходные файлы форматов BMP, JPEG, TIFF, GIF, PNG.
Сохраняет изображение в файл в формате JPEG
CODE

/*Подпрограмма преобразования строки Ansi в широкую строку
a — указатель на строку Ansi
b — указатель на указатель на широкую строку
b не должен быть инициализирован до вызова функции
функция возвращает указатель на широкую строку*/
void* __stdcall AnsiStringToWideString(void* a,void** b);
/*Подпрограмма загрузки файла с изображением и сохранения
этого изображения в формате JPEG с требуемым именем файла и квалитетом.
S — нуль-терминальная строка с именем исходного файла
D — нуль-терминальная строка с именем результатирующего файла
q — квалитет в % (1..100)
В случае успеха функция возвращает 0
В случае неудачи функция возвращает -1*/
int __stdcall LoadFromFile_And_SaveJpegToFile(char* S, char* D, unsigned long q);
int __stdcall LoadFromFile_And_SaveJpegToFile(char* S, char* D, unsigned long q)
{
int return1=0;
unsigned int t1;
void* b1_S;
void* b2_temppath;
void* b3_tempfn;
void* b4;
char* nl="GdiPlus.dll";
char* nfst="GdiplusStartup";
void* GdiplusStartup;
char* nfsh="GdiplusShutdown";
void* GdiplusShutdown;
char* nfofile="GdipLoadImageFromFile";
void* GdipLoadImageFromFile;
char* nfsfile="GdipSaveImageToFile";
void* GdipSaveImageToFile;
char* nfdi="GdipDisposeImage";
void* GdipDisposeImage;
void* hl;
void* token;
void* structi;
void* struct2;
void* IMAGE;
unsigned int clsidjpegcoder[4]={0x557cf401,0x11d31a04,0x0000739a,0x2ef31ef8};
unsigned int transformation=17;
asm
{
pushad;
mov b1_S,0;
mov b2_temppath,0;
mov b3_tempfn,0;
mov structi,0;
mov hl,0;
mov b4,0;
mov token,0;
mov IMAGE,0;
mov struct2,0;
//Найдем широкую строку с именем исходного файла
lea ebx,b1_S;
push ebx;
push S;
call AnsiStringToWideString;
or eax,eax;
jz @error1;
//широкую строку с именем исходного файла находится по указателю b1_S
//Найдем имя временного файла
push 0;
push 0;
call GetTempPath;
mov t1,eax;
push eax;
push 0;
call GlobalAlloc;
mov b2_temppath,eax;
push eax;
push t1;
call GetTempPath;
add t1,100;
push t1;
push 0;
call GlobalAlloc;
mov b3_tempfn,eax;
push eax;
push 0;
push 0;
push b2_temppath;
call GetTempFileName;
or eax,eax;
jz @error1;
//Имя временного файла в b3_tempfn
//Найдем широкую строку с именем временного файла
lea ebx,b4;
push ebx;
push b3_tempfn;
call AnsiStringToWideString;
//Широкая строка с именем временного файла в b4
//Инициализация работы с GdiPlus.dll
push nl;
call LoadLibrary;
or eax,eax;
jz @error1;
mov hl,eax;
push nfofile;
push eax;
call GetProcAddress;
mov GdipLoadImageFromFile,eax;
push nfsfile;
push hl;
call GetProcAddress;
mov GdipSaveImageToFile,eax;
push nfst;
push hl;
call GetProcAddress;
mov GdiplusStartup,eax;
push nfsh;
push hl;
call GetProcAddress;
mov GdiplusShutdown,eax;
push nfdi;
push hl;
call GetProcAddress;
mov GdipDisposeImage,eax;
push 16;
push GMEM_ZEROINIT;
call GlobalAlloc;
mov structi,eax;
mov dword ptr [eax],1;
lea ebx,token;
push 0;
push structi;
push ebx;
call GdiplusStartup;
cmp token,0;
jz @error1;
//Грузим изображение
lea ebx,IMAGE;
push ebx;
push b1_S;
call GdipLoadImageFromFile;
or eax,eax;
jnz @error1;
//Подготовка к декодированию
push 60;
push GMEM_ZEROINIT;
call GlobalAlloc;
mov struct2,eax;
//Заполним структуру с параметрами декодирования
mov dword ptr [eax],2;//Два параметра
//GUID трансформации
mov dword ptr [eax+4],0x8d0eb2d1;
mov dword ptr [eax+8],0x4ea8a58e;
mov dword ptr [eax+12],0x801014aa;
mov dword ptr [eax+16],0xf9b6b774;
mov dword ptr [eax+20],1;
mov dword ptr [eax+24],4;
lea ebx,transformation;
mov [eax+28],ebx;
//GUID квалитета
mov dword ptr [eax+32],0x1d5be4b5;
mov dword ptr [eax+36],0x452dfa4a;
mov dword ptr [eax+40],0xb35ddd9c;
mov dword ptr [eax+44],0xebe70551;
mov dword ptr [eax+48],1;
mov dword ptr [eax+52],4;
lea ebx,q;
mov [eax+56],ebx;
//Вызов функции сохранения изображения
push struct2;
lea ebx,clsidjpegcoder;
push ebx;
push b4;
push IMAGE;
call GdipSaveImageToFile;
or eax,eax;
jnz @error1;
push IMAGE;
call GdipDisposeImage;
mov IMAGE,0;
//Переименовываем временный файл
push MOVEFILE_REPLACE_EXISTING+MOVEFILE_COPY_ALLOWED;
push D;
push b3_tempfn;
call MoveFileEx;
or eax,eax;
jz @error1;
jmp @en;
@error1:mov return1,-1;
@en://Освободим занятые ресурсы
cmp IMAGE,0;
jz @f10;
push IMAGE;
call GdipDisposeImage;
@f10:
cmp b2_temppath,0;
jz @f1;
push b2_temppath;
call GlobalFree;
@f1:cmp b3_tempfn,0;
jz @f2;
push b3_tempfn;
call GlobalFree;
@f2:cmp b1_S,0;
jz @f3;
push b1_S;
call GlobalFree;
@f3:cmp b4,0;
jz @f4;
push b4;
call GlobalFree;
@f4:cmp token,0;
jz @f5;
push token;
call GdiplusShutdown;
@f5:cmp hl,0;
jz @f6;
push hl;
call FreeLibrary;
@f6:cmp structi,0;
jz @f7;
push structi;
call GlobalFree;
@f7:cmp struct2,0;
jz @f8;
push struct2;
call GlobalFree;
@f8:
popad;
};
return return1;
};
//------------------------------------------------------------
/*Подпрограмма преобразования строки Ansi в широкую строку
a — указатель на строку Ansi
b — указатель на указатель на широкую строку
b не должен быть инициализирован до вызова функции
функция возвращает указатель на широкую строку*/
void* __stdcall AnsiStringToWideString(void* a,void** b)
{
void* return1;
asm{
cmp a,0;
jz @en00;
cmp b,0;
jz @en00;
//Сохраним регистры
pushad;
//Преобразуем имя файла в строку WIDECHAR
//Сначала узнаем размер буфера
push 0;
push 0;
push dword ptr -1;
push a;
push MB_PRECOMPOSED;
push CP_ACP;
call MultiByteToWideChar;
cmp eax,0;
jz @error;
//Выделим память для буффера
mov edx,eax;
shl eax,1;
push eax;
push 0;
call GlobalAlloc;
cmp eax,0;
jz @error;
mov ebx,b;
mov [ebx],eax;
mov return1,eax;
//Преобразуем строку
push edx;
push eax;
push dword ptr -1;
push a;
push MB_PRECOMPOSED;
push CP_ACP;
call MultiByteToWideChar;
cmp eax,0;
jz @error;
jmp @en;
@error:mov return1,0;
@en:
//Восстановим регистры
popad;
@en00:
};
return return1;
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
LoadFromFile_And_SaveJpegToFile(Edit1->Text.c_str(),Edit2->Text.c_str(),50);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (OpenDialog1->Execute())
Edit1->Text=OpenDialog1->FileName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
if (OpenDialog1->Execute())
Edit2->Text=OpenDialog1->FileName;
}

Вернуться в Вопросы программирования в C++Builder