Смекни!
smekni.com

Перетворення форматів графічних файлів (стр. 3 из 3)

BMPheader[10] := 54;

Початок даних – 14 байтів заголовку №1 + 40 байтів заголовку №2.

BMPheader[14] := 40; {header size}

Розмір заголовку 2 та одночасно ідентифікатор версії – три.

BMPheader[18] := PCXheader[8]+1;
BMPheader[19] := PCXheader[9];
BMPheader[22] := PCXheader[10]+1;
BMPheader[23] := PCXheader[11];

Записується ширина та висота зображення.

BMPheader[26] := 1; {planes}

Кількість площин.

BMPheader[28] := 24; {bpp}

Бітів на піксель.

blockwrite(BMPF, BMPheader, 54);

Створенй заголовок записується на диск.

result:=1;
size:=0;
curx:=0;
while result=1 do begin

Ініціалізуються рахівники, та змінна виходу з циклу, при закінченні даних файла.

blockread(PCXF, b, 1, result);

Читається один байт, причому, якщо зчитування неможливе (кінець файлу), result прийме значення нуль, і виконається умова виходу з циклу.

if (b and $C0) = $C0 then begin
b:=b and $3F;
blockread(PCXF, val, 1, result);
end else begin
val:=b;
b:=1;
end;

Стандартний алгоритм розпаковки RLE-закодованих даних формату PCX. Тут обробляється зчитаний байт та якщо потрібно зчитується наступний, і на виході маємо b– кількість повторів, val– значення, яке потрібно повторити.

gotoxy(1, wherey); write(size); clreol; inc(size);

Для індикаціі того, що програма щось робить, а не зависла, на екран виводиться кількість вже перетворених пікселів, яка (кількість) після цього інкрементується.

for i:=1 to b do begin
buf[curx]:=val;
inc(curx);
end;

Відбувається запис у буфер значення b valразів.

if (curx=BPL*3) then begin
for i:=0 to BPL-1 do begin
blockwrite(BMPF, buf[i+2*BPL], 1);
blockwrite(BMPF, buf[i+BPL], 1);
blockwrite(BMPF, buf[i+000], 1);
end;
curx:=0;
end;

Коли ми зчитали увесь рядок у буфер, час його записати. Але через те, що RGB дані у PCX форматі розбиті на площини, запис йде з трьох точок буферу, що поступово зміщуються. Зауважте обернений формат запису триплетів у форматі BMP, спочатку йде B, потім G, а потім R. У кінці ми переводимо вказівник знову на початок буферу.

end;
writeln;
close(PCXF);
close(BMPF);

Закінчили читати файл й записувати тимчасовий.

Починаємо перевертання тимчасового файлу у нормальний формат BMP.

assign(PCXF, 'dollar.tmp');
reset(PCXF, 1);
assign(BMPF, 'dollar.bmp');
rewrite(BMPF, 1);

Спочатку, як завжди, відкриємо файли. Врахуйте, що тимчасовий файл відкривається змінною, що раніше відповідала PCX файлу. Так зроблено для мінімізації кількості змінних.

blockread(PCXF, BMPheader, 54);
blockwrite(BMPF, BMPheader, 54);

Зчитаємо й запишемо заголовок без змін. Будемо зчитувати файл по рядкам з кінця, а записуватимемо з початку.

for i:=1 to HGT do begin

Як не дивно, зчитувати рядки потрібно стільки раз, скільки у нас рядків.

pos1 := filesize(PCXF)-(BPL*3*i);

Визначається позиція кожного рядку у файлі: від кінця файлу віднімаємо i рядків довжиною BPL*3 (*3 тому, що RGB).

gotoxy(1, wherey); write(pos1); clreol;

Просто виводимо цю позицію на екран.

seek(PCXF, pos1);
blockread(PCXF, buf, BPL*3);
blockwrite(BMPF, buf, BPL*3);
end;

Переходимо до визначеной позиції, зчитуємо і записуємо рядок зображення.

close(PCXF);
close(BMPF);
writeln;
end.

У кінці бажано позакривати все, що відкривали. Можна було б також витерти тимчасовий файл.

Висновки

Завданням даної роботи було дослідження основних принципів перетворення форматів графічних файлів. У роботі наведено різні класифікації графічних форматів. Розглянуто можливі галузі застосування цих форматів, як то: Internet, друковані видання, електроні презентації. Також наведено детальний опис усіх можливих варіантів перетворення одного формату в інший, зазначено типові проблеми, які при цьому виникають. Крім того створено програму перетворення для двох конкретних растрових форматів. Під час роботи над програмою ретельно досліджено будову форматів PCX та BMP, описано алгоритм їхнього перетворення, пояснено реалізацію алгоритму на мові Pascal.

Література

1. Д. Мюррей, У. Райпер "Энциклопедия форматов графических файлов", BHV, Киев, 1997.

2. Р. Водески "Графика для Web", Диалектика, Киев, 1998.

3. ftp://ftp.mv.com/pub/ddj/1994/1194.09/bmp.zip

4. ftp://x2ftp.oulu.fi/pub/msdos/programming/formats

5. ftp://telva.ccu.uniovi.es/pub/graphics/file.formats

6. Журнал "ЧИП", 9/97, стр. 58, "Графические форматы BMP, GIF, JPEG, PNG и FLASHPIX"

Додаток 1

Повний текст програми перетворення.

Uses
crt;
var
PCXF, BMPF: file;
PCXheader: array [0..127] of byte;
BMPheader: array [0..53] of byte;
i, result, curx, HGT: integer;
buf: array [0..1959] of byte;
b, val: byte;
size, pos1, BPL: longint;
begin
assign(PCXF, 'dollar.pcx');
reset(PCXF, 1);
assign(BMPF, 'dollar.tmp');
rewrite(BMPF, 1);

blockread(PCXF, PCXheader, 128);
for i:=0 to 53 do begin
BMPheader[i]:=0;
end;

writeln('W: ', PCXheader[9]*256+PCXheader[8]+1);
HGT := PCXheader[11]*256+PCXheader[10]+1;
writeln('H: ', HGT);
BPL := PCXheader[67]*256+PCXheader[66];

BMPheader[0] := $42; {header word}
BMPheader[1] := $4D;
BMPheader[10] := 54;
BMPheader[14] := 40; {header size}
BMPheader[18] := PCXheader[8]+1;
BMPheader[19] := PCXheader[9];
BMPheader[22] := PCXheader[10]+1;
BMPheader[23] := PCXheader[11];
BMPheader[26] := 1; {planes}
BMPheader[28] := 24; {bpp}
blockwrite(BMPF, BMPheader, 54);
result:=1;
size:=0;
curx:=0;
while result=1 do begin
blockread(PCXF, b, 1, result);
if (b and $C0) = $C0 then begin
b:=b and $3F;
blockread(PCXF, val, 1, result);
end else begin
val:=b;
b:=1;
end;
gotoxy(1, wherey); write(size); clreol; inc(size);
for i:=1 to b do begin
buf[curx]:=val;
inc(curx);
end;
if (curx=BPL*3) then begin
for i:=0 to BPL-1 do begin
blockwrite(BMPF, buf[i+2*BPL], 1);
blockwrite(BMPF, buf[i+BPL], 1);
blockwrite(BMPF, buf[i+000], 1);
end;
curx:=0;
end;
end;
writeln;
close(PCXF);
close(BMPF);

assign(PCXF, 'dollar.tmp');
reset(PCXF, 1);
assign(BMPF, 'dollar.bmp');
rewrite(BMPF, 1);
blockread(PCXF, BMPheader, 54);
blockwrite(BMPF, BMPheader, 54);
for i:=1 to HGT do begin
pos1 := filesize(PCXF)-(BPL*3*i);
gotoxy(1, wherey); write(pos1); clreol;
seek(PCXF, pos1);
blockread(PCXF, buf, BPL*3);
blockwrite(BMPF, buf, BPL*3);
end;
close(PCXF);
close(BMPF);
writeln;
end.