Помощь - Поиск - Пользователи - Календарь
Полная версия: вывод на экран Pcx
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Akira
Как вывести графический файлик PCX на экран?
Очень срочно надо, а то что видел почему-то не работает :-(
sembler
Сорри, я зарегаться не успел. Эту тему я создавал.
Так получилось, что это курсовая работа. Хотя мы до этого (1ый курс) с графикой вообще не работали, так вот, всякий дет.сад вроде массивов/циклов я, конечно знаю, а вот с графикой работать не умею... А курсовик надо срочно написать.
Итак, в документации к Pcx написано, что размеры изображения и прочая инфа находятся в заголовке:

class {
      char Manufacturer;      // Постоянный флаг 10 = ZSoft .PCX
      char Version;           // 0 = Версия 2.5
                              // 2 = Версия 2.8 с информацией о палитре
                              // 3 = Версия 2.8 без информации о палитре
                              // 5 = Версия 3.0
      char Encoding;          // 1 = .PCX кодирование длинными сериями
      char BitsPerLayer;      // Число бит на пиксел в слое
      unsigned int Xmin;      // Размеры изображения
      unsigned int Ymin;      // Размеры изображения
      unsigned int Xmax;      // Размеры изображения
      unsigned int Ymax;      // Размеры изображения
      unsigned int HRes;      // Горизонтальное разрешение создающего устройства
      unsigned int VRes;      // Вертикальное разрешение создающего устройства
      char Colormap[48];      // Набор цветовой палитры (см. далее текст)
      char Reserved;
      char NPlanes;           // Число цветовых слоев
      unsigned int BPL;       // Число байт на строку в цветовом слое
                              // (для PCX-файлов всегда должно быть четным)
      unsigned int Palette;   // Как интерпретировать палитру:
                              // 1 = цветная/черно-белая,
                              // 2 = градации серого
      char Filler[58];        // Заполняется нулями до конца заголовка
}

Вопрос намбер один, а как эти самые заголовки прочитать и передать соответствующим переменным?
И что такое "Горизонтальное/Вертикальное разрешение создающего устройства"?
Для начала, думаю, мне с этим надо разобраться, а уже потом по пикселю вывести изображение?
Altair
надо поискать на исходниках.ру, там я где-то видел вывод PCX
Цитата
Вопрос намбер один, а как эти самые заголовки прочитать и передать соответствующим переменным?

1) Открываем файл как НЕ типизированный!
2) Читаем с помощью BlockRead из начала файла в переменную, имеющую тип заголовка.
(точно так, как мы читаем из BMP - посмотрите модуль для BMP в тестовом форуме)
sembler
Очень извиняюсь, наверно я жутко тормажу. Вчера, опять, сел за эту программку - написал такой
кусок кода. Дык вот, при запуске (даже после компиляции) программка вылетает ничего не напечатав. Может я жутко тормажу? подскажите плиз...

program z1;
type

RGB = record
 Red,
 Green,
 Blue : Byte;
end;

 header=record
 Maker        : Byte;
 Version      : Byte;
 Code         : Byte;
 BitsPerPixel : Byte;
 XLow         : Word;
 YLow         : Word;
 XHigh        : Word;
 YHigh        : Word;
 Hres         : Word;
 Vres         : Word;
 Palette      : array [0..15] of RGB;
 VMode        : Byte;
 PlaneCount   : Byte;
 BytesPerLine : Word;
 Reserved     : array [0..59] of byte;
end;

var pcx:header;
  f:file;

begin
       assign(f,'file.pcx');
       reset(f);
       blockread(f, pcx, 128);
       close(f);
       write(pcx.Hres);
end.
virt
попробуй написать
       reset(f,1);

1 это колво байт в записи которая считывается blockread'oм. По умолчанию оно равно 128 -- получается ты считываешь 128*128 байт.

**после как допишешь кинь ссылочку на свою прогу.
Dark
Гарантированно выводит PCX с любым размером до 800*600 256 цветов
Используется моя личная библиотека VESA - VesaType и Vesa256.
Цитата
И, если не сложно и не жалко времени, можешь объяснить, на пальцах, как ты конвертишь палитру?

в .pcx у нас хранится 768 байт, но палитра имеет значение от 0 до 63, поэтому я значение каждого байта палитры делю на 4 (256/4=64), а потом передаю все 768 байт биосовской процедуре установки палитры.

Реализация перенесена сюда: FAQ: Модули для вывода графики
sembler
А не подскажите, как быть с 16ти цветными изображениями? Т.е. как инициализировать палитру и преобразовывать цвета в стандартные, которые в putpixel'е.
желательно, без дополнительных модулей типа VESA (за которые респект)..
Dark
ну, 16 цветовая палитра находится в заголовке
ColorMap    : array[0..47] of byte;{палитра для 16ц режимов}


установка - так же как и в 256 цветном, но можно средствами паскаля...

SetRGBPalette по моему smile.gif
GLuk
Сколько можно жевать Товарищи??!! blink.gif blink.gif blink.gif
Разве в поиске этого нету!!!!!!!!!???????
У меня в архиве около 10 реализаций вывода PCX, да и в поисковиках их море...
sembler
Хельп! Сдача через пару дней, а у меня нифига не готово...
Методом тыка и удаления того, что относится к 256ти цветному pcx'у, в коде Дарка написал вот это:

program z1;
uses crt, graph;
type

Tarray64k=array[0..65534] of byte;

RGB = record
Red,
Green,
Blue: Byte;
end;

header=record
Maker : Byte;
Version : Byte;
Code : Byte;
BitsPerPixel : Byte;
XLow : Word;
YLow : Word;
XHigh : Word;
YHigh : Word;
Hres : Word;
Vres : Word;
Palette : array [0..15] of RGB;
VMode : Byte;
PlaneCount : Byte;
BytesPerLine : Word;
Reserved : array [0..59] of byte;
end;

var pcx:header;
f:file;
gd,gm,i,j:integer;
x,y:word;
buf:^Tarray64k;
fsize:longint;
c:byte;
res:word;
count:longint;
m:longint;
ex,ey:word;
l:word;
adress:string;

begin readln(adress);
assign(f,adress);
reset(f,1);
blockread(f, pcx, 128);
gd:=detect;
InitGraph(gd, gm, '');
fsize:=filesize(f);
with pcx.palette[i] do setRGBpalette(i,red,green,blue);
{попытка объявления палитры}

seek(f,128);

InitGraph(gd, gm, '');
getmem(buf,65535);
gd:=detect;
x:=0; y:=0; c:=0; count:=0;

for i:= 1 to (fsize div 65535)+1 do
begin
blockread(f,buf^,65535,res);
ey:=pcx.yhigh-pcx.ylow+1;
ex:=pcx.xhigh-pcx.xlow+1;
m:=0;
while (m<res) and (y<ey) do
begin
if c<>0
then
begin
for l:=1 to c do
begin
PutPixel(x,y,buf^[m]);
inc(x);
end;
inc(count,c);
c:=0;
end
else
if (buf^[m] and $c0=$c0)
then
c:=buf^[m] and $3f else
begin
PutPixel(x,y,buf^[m]);
Inc( X );
inc(count,1);
end;
inc (m);
IF X >= eX THEN
BEGIN
x:=0;
Inc( Y )
END
end;
end;
freemem(buf,65535);
close(f);

repeat;
until keypressed;
CloseGraph;
end.


В идеале, она должна рисовать 16 цветные pcx'ы. На деле - палитру я объявляю неправильно и, почему-то, рисунка выходит два, а не один.. somebody help me please!

2GLuk
В форуме, впоиске минимум 4 символа, так, что по pcx я ничего не нашёл...
А что за архив? кинь линку, плиз.
sembler
Я сделал это! Ура! Точнее, я посоеденял куски разных кодов в один smile.gif Большущее спасибо всем, кто мне помог. Особенно Дарку, я требую, чтобы модеры вручили ему один "плюсик", а лучше не один.

Работает это в 256 цветах, на драйвере svga256.bgi. Короче всем ещё раз спасибо!

program kurswork;
uses crt, graph;
type

Tarray64k=array[0..65534] of byte;

RGB = record
Red,
Green,
Blue: Byte;
end;

header=record
Maker : Byte;
Version : Byte;
Code : Byte;
BitsPerPixel : Byte;
XLow : Word;
YLow : Word;
XHigh : Word;
YHigh : Word;
Hres : Word;
Vres : Word;
Palette : array [0..15] of RGB;
VMode : Byte;
PlaneCount : Byte;
BytesPerLine : Word;
Reserved : array [0..59] of byte;
end;

var Palette : array[0..255] of RGB;
pcx : header;
f : file;
gd,gm,i,j : integer;
x,y : word;
buf : ^Tarray64k;
fsize : longint;
c : byte;
res : word;
count : longint;
m : longint;
ex,ey : word;
l : word;
adress : string;

begin readln(adress);
assign(f,adress);
reset(f,1);
blockread(f, pcx, 128);

gd:= InstallUserDriver('SVGA256',@gd); gm:= 9;
InitGraph(gd, gm, '');

fsize:=filesize(f);
Seek(f, fsize-768);
for i:=0 to 255 do
begin
BlockRead(f, Palette[i].red, 1);
Palette[i].red:=Palette[i].red shr 2;
BlockRead(f, Palette[i].green, 1);
Palette[i].green:=Palette[i].green shr 2;
BlockRead(f, Palette[i].blue, 1);
Palette[i].blue:=Palette[i].blue shr 2;
end;
for i:=0 to 255 do
begin
port[$3C6]:= $FF;
port[$3C8]:= i;
port[$3C9]:= Palette[i].red;
port[$3C9]:= Palette[i].green;
port[$3C9]:= Palette[i].blue;
end;

seek(f,128);
getmem(buf,65535);

x:=0; y:=0; c:=0; count:=0;

for i:= 1 to (fsize div 65535)+1 do
begin
blockread(f,buf^,65535,res);
ey:=pcx.yhigh-pcx.ylow+1;
ex:=pcx.xhigh-pcx.xlow+1;
m:=0;
while (m<res) and (y<ey) do
begin
if c<>0
then
begin
for l:=1 to c do
begin
PutPixel(x,y,buf^[m]);
inc(x);
end;
inc(count,c);
c:=0;
end
else
if (buf^[m] and $c0=$c0)
then
c:=buf^[m] and $3f else
begin
PutPixel(x,y,buf^[m]);
Inc( X );
inc(count,1);
end;
inc (m);
IF X >= eX THEN
BEGIN
x:=0;
Inc( Y )
END
end;
end;
freemem(buf,65535);
close(f);

repeat;
until keypressed;
CloseGraph;
end.

APAL
По просьбе трудящихся рейтинг был поднят! smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.