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

 
BMP формат, Попиксельный вывод bmp файла
coersion
  Отправлено: 18.09.2005, 21:53


Не зарегистрирован







Написал программу вывода изображений (только 256-цветных). Программа читает информацию об изображении из заголовка, затем палитру и на компонент TImage выводит попиксельно изображение.

Внимание вопрос: почему выводятся не все 256 цветные изображения.
Например набросанные в Paint-e карандашом выводятся без проблем (и даже некоторые сложнее — файл 4.bmp), а часть картинки какой-нибудь сложной природы (хотя и 256-ти цветной) нет. Проверка на соответствие 256bmp осуществляется.

Исходники с примерами картинок прилагаются.

User Attached Image Скачать файл
lab1.zip


Sl@Sh
Отправлено: 19.09.2005, 10:35


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

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



Скачать ваш исходник не удалось (с сетью проблемы sad.gif ) поэтому есть вопрос : Как осуществляется вывод на изображение.

Возможно проверять на 256-цветность не стоит. Выложите код пож. а там видно будет.
Guest
Отправлено: 19.09.2005, 20:40


Не зарегистрирован







QUOTE (Sl@Sh @ 19/09/2005, 10:35)
Скачать ваш исходник не удалось (с сетью проблемы sad.gif ) поэтому есть вопрос : Как осуществляется вывод на изображение.

Возможно проверять на 256-цветность не стоит.  Выложите код пож. а там видно будет.

Вот Unit1.cpp:
CODE

//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <string.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define RGB(r, g ,b)  ((DWORD) (((BYTE) (r) | \
   ((WORD) (g) << 8)) | \
   (((DWORD) (BYTE) (b)) << 16)))
TForm1 *Form1;


struct Palitra
{
       BYTE    blue;
       BYTE    green;
       BYTE    red;
       BYTE    pNULL;
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------



void __fastcall TForm1::Help1Click(TObject *Sender)
{
       ShowMessage("Выберите в файловом броузере файл для просмотра AND DO DOUBLE CLICK");
}
//---------------------------------------------------------------------------

void __fastcall TForm1::About1Click(TObject *Sender)
{
       ShowMessage("Make by Ploschanskiy Aleksey, e28, FACE, BSTU");
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FileListBox1DblClick(TObject *Sender)
{
       FILE *ptrOnBmpFile;
       DWORD    dwData;
       WORD    wData;
       int isBMP = 1;
       DWORD dwFileSize = 0;
       struct Palitra palitra[256];
       BYTE    ptr;
       DWORD   color;

//----------------------READ FILE---------------------------
       if ((ptrOnBmpFile = fopen(FileListBox1->FileName.c_str(), "r")) == NULL)
       {
               AnsiString message = "Can't open file: " + FileListBox1->FileName;
               ShowMessage(message);
               exit(1);
       }

       // Seek to end of file
       fseek(ptrOnBmpFile, 0, SEEK_END);
       // Get the file size
       dwFileSize = ftell(ptrOnBmpFile);
       // Seek to begin of file
       rewind(ptrOnBmpFile);
//----------------------READ FILE---------------------------

//----------------------IS BMP?-----------------------------
       fread(&wData, 2, 1, ptrOnBmpFile);      // читаем сигнатуру "BM"
       if (wData != 0x4d42)   isBMP = 0;       // сигнатура "BM" в начале файла
       fread(&dwData, 4, 1, ptrOnBmpFile);     // читаем размер файла
       if (dwFileSize != dwData)      isBMP = 0;    // соответствие размеров
       if (isBMP == 0)
       {
               ShowMessage("Структура файла не соответствует bmp формату!");
               exit(1);
       }
//----------------------IS BMP?-----------------------------

//----------------------FILE INFO---------------------------
       Label2->Caption = FileListBox1->FileName;
       Label4->Caption = dwFileSize;

       fread(&dwData, 4, 1, ptrOnBmpFile);     // читаем и отбрасываем зарезервированные байты
       fread(&dwData, 4, 1, ptrOnBmpFile);     // смещение начала битового массива от начала файла
       Label6->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);     // длина информационного заголовка
       Label8->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);     // ширина изображения
       Label10->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);     // высота изображения
       Label12->Caption = dwData;

       fread(&wData, 2, 1, ptrOnBmpFile);     // число плоскостей
       Label14->Caption = wData;

       fread(&wData, 2, 1, ptrOnBmpFile);     // глубина цвета (бит на точку)
       if (wData != 8)
       {
               ShowMessage("Программа может читать файлы с цветовой палитрой 256 цветов ");
               exit(1);
       }
       Label16->Caption = wData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // тип компрессии
       Label18->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // размер изображения
       Label20->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // Горизонтальное разрешение, точки на метр
       Label22->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // Вертикальное разрешение, точки на метр
       Label24->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // Число используемых цветов (0 — максимально возможное для данной глубины цвета)
       Label26->Caption = dwData;

       fread(&dwData, 4, 1, ptrOnBmpFile);      // Число основных цветов
       Label28->Caption = dwData;

//----------------------FILE INFO---------------------------

//----------------------SHOW FORM---------------------------
       Form2->Caption          = FileListBox1->FileName;
       Form2->Width            = Label10->Caption.ToInt();
       Form2->Image1->Width    = Form2->Width;
       Form2->Height           = Label12->Caption.ToInt();
       Form2->Image1->Height   = Form2->Height;
       Form2->Visible          = true;
//----------------------SHOW FORM---------------------------

//----------------------DRAW CANVAS-------------------------
       fread(palitra, 4, 256, ptrOnBmpFile);      // Читаем палитру

       for (int y = Label12->Caption.ToInt() — 1; y >= 0; y--)
       for (int x = 0; x < Label10->Caption.ToInt(); x++)
       {
               fread(&ptr, 1, 1, ptrOnBmpFile);        // индекс цвета

               Form2->Image1->Canvas->Pixels[x][y] = RGB(palitra[ptr].red, palitra[ptr].green, palitra[ptr].blue);
       }
//-----------------------DRAW CANVAS------------------------

}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
       Label2->Caption = "";
       Label4->Caption = "";
       Label6->Caption = "";
       Label8->Caption = "";
       Label10->Caption = "";
       Label12->Caption = "";
       Label14->Caption = "";
       Label16->Caption = "";
       Label18->Caption = "";
       Label20->Caption = "";
       Label22->Caption = "";
       Label24->Caption = "";
       Label26->Caption = "";
       Label28->Caption = "";
}
//---------------------------------------------------------------------------

Sl@Sh
Отправлено: 20.09.2005, 16:36


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

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



Честно говоря я не пойму смысла ваших стараний.
Зачем такая сложность, когда можно всё решить в рамках класса TBitmap ?
Еще можно понять если вы без использования vcl пытаетесь сделать, но вы использоваете vcl и изобретаете велосипед.

Особенно интерестно вот это действие :
CODE

      Label2->Caption = "";
      Label4->Caption = "";
      Label6->Caption = "";
      Label8->Caption = "";
      Label10->Caption = "";
      Label12->Caption = "";
      Label14->Caption = "";
      Label16->Caption = "";
      Label18->Caption = "";
      Label20->Caption = "";
      Label22->Caption = "";
      Label24->Caption = "";
      Label26->Caption = "";
      Label28->Caption = "";


Инспектор ведь есть.

P.S.: Как видите я прямого ответа не дал т.к. не вижу смысла в таком сложном подходе.

Отредактировано Sl@Sh — 20/09/2005, 16:40
Doga
Отправлено: 20.09.2005, 18:22


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

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



Да и пиксельная прорисовка занимает довольно много времени. Лучше пользоваться уже существующим наборм методов Canvas — гораздо быстрее...
Guest
Отправлено: 20.09.2005, 19:54


Не зарегистрирован







Дело не в том чем пользоваться, а в том, что не все файлы с 256-ти цветной палитрой открываются.
Sl@Sh
Отправлено: 21.09.2005, 17:08


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

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



Да нет, в этом-то и дело. Из вашего кода видно, что подход к решению вашей задачи не играет принципиальной роли. Знаю, иногда бывает хочется всё сделать самому, но это не всегда правильно. Doga правильно заметил. Скорость тоже важна, а Canvas->Pixels работает медленнее чем метод ScanLine (намного медленнее !!!).

Кстати какой результат вы получаете при вашем коде ? Ошибок при выполнении нет ? Если есть (и вы это имеете ввиду) то возможно дело в строке : Form2->Image1->Canvas->Pixels[x][y] = RGB(palitra[ptr].red, palitra[ptr].green, palitra[ptr].blue);

У меня как-то постоянно выдавало ошибку при таком действии. Избавился просто приведением правой части к TColor

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