Помощь - Поиск - Пользователи - Календарь
Полная версия: вывод на экран 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
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.