Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Нужно програмно создать BMP файл, если можно обьясните как для чайника

1.8K
05 апреля 2004 года
Andreww
81 / / 02.01.2004
Здравствуйте! У меня такой вопрос. Есть файл в виде координат точек, и их цвет (цвет каждой точки, если это важно - то он будет задаваться градациями серого [черно-белая картинка]). Из этих точек нужно слепить BMP файл. (Просто раньше эти точки выводились на экран в DOS режиме, а теперь нужно их запихивать в BMP, потому что прога которая с ними будет работать понимает BMP формат).
Есть много описаний структуры bmp файла, я их пересмотрел (даже из msdn находил инфу), но все равно не могу понять как мне с этим работать. Даже не представляю с какой стороны походить. Может кто поможет разобраться, сделать примерно следующее: например есть две точки, координаты и цвет: (10, 10, белый); (20, 30, серый). Как можно програмно создать bmp с этими точками?
Или может исходник есть где используется что-то подобное? Вышлите пожалуйста на мыло [email]andreww@svitonline.com[/email] буду очень-очень благодарен.
4.6K
05 апреля 2004 года
mustlive
37 / / 27.03.2004
Цитата:
Originally posted by Andreww
Здравствуйте! У меня такой вопрос. Есть файл в виде координат точек, и их цвет (цвет каждой точки, если это важно - то он будет задаваться градациями серого [черно-белая картинка]). Из этих точек нужно слепить BMP файл. (Просто раньше эти точки выводились на экран в DOS режиме, а теперь нужно их запихивать в BMP, потому что прога которая с ними будет работать понимает BMP формат).
Есть много описаний структуры bmp файла, я их пересмотрел (даже из msdn находил инфу), но все равно не могу понять как мне с этим работать. Даже не представляю с какой стороны походить. Может кто поможет разобраться, сделать примерно следующее: например есть две точки, координаты и цвет: (10, 10, белый); (20, 30, серый). Как можно програмно создать bmp с этими точками?
Или может исходник есть где используется что-то подобное? Вышлите пожалуйста на мыло [email]andreww@svitonline.com[/email] буду очень-очень благодарен.



Если кратко, то у BMP-файла есть заголовок, который идет в начале (там много нужной и бесполезной инфромации, в основном, конечно, нужной :)

Вся проблема в том (в твоем случае), что формат BMP не может сохранять что-то по точкам, в нем хранится некая прямоугольная область. Т.е. например, если у тебя черный экран, и есть две точки (10, 10, белый); (20, 30, серый), то тебе нужно сохранять область экрана (10,10,30,30) - это по-минимуму. По-другому не выйдет. В файле будет все забито нулями (черный цвет) кроме твоих 2-х точек. Поэтому BMP такие здоровые

1.8K
05 апреля 2004 года
Andreww
81 / / 02.01.2004
Цитата:
Originally posted by mustlive


Если кратко, то у BMP-файла есть заголовок, который идет в начале (там много нужной и бесполезной инфромации, в основном, конечно, нужной :)

Вся проблема в том (в твоем случае), что формат BMP не может сохранять что-то по точкам, в нем хранится некая прямоугольная область. Т.е. например, если у тебя черный экран, и есть две точки (10, 10, белый); (20, 30, серый), то тебе нужно сохранять область экрана (10,10,30,30) - это по-минимуму. По-другому не выйдет. В файле будет все забито нулями (черный цвет) кроме твоих 2-х точек. Поэтому BMP такие здоровые



Ну, у меня на самом деле не 2 точки, а немеряно точек (дифракционная картина, если интересно); а выбор именно бмп основан на том что программа куда это передается работает с бмп.
Почитать ничего нету по этому поводу (в смысле как записать), а? А то сильно надо. Очень сильно :-)

4.6K
06 апреля 2004 года
mustlive
37 / / 27.03.2004
Цитата:
Originally posted by Andreww


Ну, у меня на самом деле не 2 точки, а немеряно точек (дифракционная картина, если интересно); а выбор именно бмп основан на том что программа куда это передается работает с бмп.
Почитать ничего нету по этому поводу (в смысле как записать), а? А то сильно надо. Очень сильно :-)



Да хоть интерференционная :) BMP хорош только тем, что открывается проще других форматов, так как содержит битовую карту (bitmap), никаких сжатий и т.п. как например у JPG.

А не пробовал здесь поискать? На codenet куча исходников и книжек. Можно в поиске по сайту написать "bmp" и удивляться, сколько информации будет найдено :) Ну, или зайти в обычный книжный магазин, поискать что-нибудь с примерами. Я помочь исходником не могу, потому что готового ничего нет, а писАть лениво, время нужно. Но я уверяю, ничего сложного нет

4.6K
06 апреля 2004 года
mustlive
37 / / 27.03.2004
Вот, кстати, в хелпе по билдеру нашел (вообще, посмотри каталог Examples, там этого добра навалом):

The picture object can load and save graphics in several formats, and you can create and register your own graphic-file formats so that picture objects can load and store them as well.
To save the contents of an image control in a file, call the SaveToFile method of the image control’s Picture object.
The SaveToFile method requires the name of a file in which to save. If the picture is newly created, it might not have a file name, or a user might want to save an existing picture in a different file. In either case, the application needs to get a file name from the user before saving, as shown in the next section.

The following pair of event handlers, attached to the File|Save and File|Save As menu items, respectively, handle the resaving of named files, saving of unnamed files, and saving existing files under new names.

void __fastcallTForm1::Save1Click(TObject *Sender)

{
if (!CurrentFile.IsEmpty())
Image->Picture->SaveToFile(CurrentFile); // save if already named
else SaveAs1Click(Sender); // otherwise get a name
}

void __fastcallTForm1::SaveAs1Click(TObject *Sender)

{
if (SaveDialog1->Execute()) // get a file name
{
CurrentFile = SaveDialog1->FileName; // save user-specified name
Save1Click(Sender); // then save normally
}
}
487
06 апреля 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Здравствуйте! У меня такой вопрос. Есть файл в виде координат точек, и их цвет (цвет каждой точки, если это важно - то он будет задаваться градациями серого [черно-белая картинка]). Из этих точек нужно слепить BMP файл. (Просто раньше эти точки выводились на экран в DOS режиме, а теперь нужно их запихивать в BMP, потому что прога которая с ними будет работать понимает BMP формат).
Есть много описаний структуры bmp файла, я их пересмотрел (даже из msdn находил инфу), но все равно не могу понять как мне с этим работать. Даже не представляю с какой стороны походить. Может кто поможет разобраться, сделать примерно следующее: например есть две точки, координаты и цвет: (10, 10, белый); (20, 30, серый). Как можно програмно создать bmp с этими точками?
Или может исходник есть где используется что-то подобное? Вышлите пожалуйста на мыло [email]andreww@svitonline.com[/email] буду очень-очень благодарен.



Все очень просто:

void __fastcall bmp_store(void)
{
Graphics::TBitmap *bmp=new Graphics::TBitmap();
bmp->PixelFormat=pf24bit;
/*
pf1bit - монохромные битмапы
pf4bit - палетризованные 16 цветные
pf8bit - палетризованные 256 цветные
pf15bit - 5:5:5 (держит только Windows9x)
pf16bit - 5:6:5
pf24bit - RGB
pf32bit - RGBA
*/
bmp->Width=100;
bmp->Height=100;
/*
для доступа к данным битмапа есть два способа:
1. Через канву.
*/
bmp->Canvas->Pixels[10][10]=clWhite;
bmp->Canvas->Pixels[20][30]=clGray;
bmp->Canvas->Pen->Color=clRed;
bmp->Canvas->Pen->MoveTo(0,0);
bmp->Canvas->Pen->LineTo(100,100);
/*
Способ второй - непосредственно через сканы:
Только в этом случае важно помнить следующее - количество бит отводимых под каждый пиксел в этом случае зависит непосредственно от пиксельного формата заданного для изображения.
pf1bit - 1 байт на 8 точек по горизонтали.
pf4bit - 1 байт на 2 точки
pf8bit - байт на точку
pf15bit и pf16bit - 2 байта на точку
pf24bit - 3 байта на точку
pf32bit - 4 байта на точку.

Ну еще и помнить следующее - у майкросовта все никак у людей - цветовая ориентация не RGB а BGR :) Все их на голубизну тянет.

Пример:
*/
BYTE *scan=(BYTE*)bmp->ScanLine[10];
// (10,10,белый цвет)
*(scan+10*3)=0xFF;
*(scan+10*3+1)=0xFF;
*(scan+10*3+2)=0xFF;
// (20,30,серый цвет)
scan=(BYTE*)bmp->ScanLine[30];
*(scan+20*3)=0x80;
*(scan+20*3+1)=0x80;
*(scan+20*3+2)=0x80;
// ну вобщем все в таком духе.
// А теперь сохраним полученный результат:
bmp->SaveToFile("c:\test.bmp");
// Готово собственно.
delete bmp;
}

Да, отмечу - форматы pf15bit,pf16bit,pf32bit - понимаются не всеми прогами - фотошоп например стал их поддерживать только в 7 версии.
Вобщем смотри хелп по TBitmap

1.8K
06 апреля 2004 года
Andreww
81 / / 02.01.2004
Спасибо! Сейчас "помедитирую" над кодом, может чего-то и выйдет.
1.8K
06 апреля 2004 года
Andreww
81 / / 02.01.2004
Еще раз спасибо, только что убедился что это все отлично работает. Я остановился на втором варианте (который Вы назвали "через сканы", потом почитаю как это по-научному называется).
Очень прикольно то что действительно не RGB, а BGR - для задания цвета я открыл свою книгу по ХТМЛ, нашел красный, и задал как ff0000 - получился синий :-) поменял на 0000ff - красный :-))).

Можно еще пару вопросов, чтоб уже так сказать на этом сделать логическое завершение?

1) Что собой представляет ScanLine[30]? Это 30-я позиция массива ScanLine? И это мы в ScanLine[Y] подставляем координату Y, а в *(scan+X*3)=0x80 - координату X?
Что происходит вот здесь : scan=(BYTE*)bmp->ScanLine[30]? bmp - это динамический массив который мы создали, потом преобразовали его к типу BYTE, да? А вот это что: (BYTE*)bmp->ScanLine[30]?
Graphics - это класс в котором все описано, а мы только пользуемся его членами/методами?
(Заметно, наверно какой я ламер в С++, просто приходится перелазить с Си на С++, а то есть угроза отстать от прогресса :-))

2) Как можно сделать чтоб фон рисунка был черным а не белым? Зарисовать все черными точками, а потом поверху рисовать своими серо-белыми? Или можно как то сразу с черным фоном создать?
В рез-те у меня должна получиться бело-серая картинка на черном фоне.

Если будете выбирать на какой вопрос отвечать то лучше на второй, плз. Хотя теор-часть (первый вопрос) меня тоже очень интересует.
4.6K
07 апреля 2004 года
mustlive
37 / / 27.03.2004
Цитата:
Originally posted by Andreww


1) Что собой представляет ScanLine[30]? Это 30-я позиция массива ScanLine? И это мы в ScanLine[Y] подставляем координату Y, а в *(scan+X*3)=0x80 - координату X?
Что происходит вот здесь : scan=(BYTE*)bmp->ScanLine[30]? bmp - это динамический массив который мы создали, потом преобразовали его к типу BYTE, да? А вот это что: (BYTE*)bmp->ScanLine[30]?


ScanLine[30]-30-я строка битмапа, ScanLine[10] - 10-я и т.п.

Тот пример (но с комментариями):

// указатель на начало 10-й строки битмапа суем в
scan
BYTE *scan=(BYTE*)bmp->ScanLine[10];

/* это все обычная работа с указателями. С++ здесь ни при чем :) Пример написан с расчетом на то, что цвет точки задается 3-х байтовым значением. 10 в данном случае - это 10-я точка в строке - мы же сейчас рассматриваем точку с координатами (10,10). */
*(scan+10*3)=0xFF; - код B
*(scan+10*3+1)=0xFF; - код G
*(scan+10*3+2)=0xFF; - код R

короче, в результате выполнения этого куска точка с координатами (10,10) будет белий-белий

Цитата:
Graphics - это класс в котором все описано, а мы только пользуемся его членами/методами?
(Заметно, наверно какой я ламер в С++, просто приходится перелазить с Си на С++, а то есть угроза отстать от прогресса :-))



Ну, вроде того :) А ты что думал? Волшебное слово такое? :)


Цитата:
2) Как можно сделать чтоб фон рисунка был черным а не белым? Зарисовать все черными точками, а потом поверху рисовать своими серо-белыми? Или можно как то сразу с черным фоном создать?
В рез-те у меня должна получиться бело-серая картинка на черном фоне.



Точками зарисовывать вообще-то долго. Лучше сделать заливку прямоугольной области (называться будет как-нибудь навроде FillRect, точно сказать не могу, так как билдером не пользуюсь). Или создать битмап черного цвету изначально

487
10 апреля 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by Andreww
Graphics - это класс в котором все описано, а мы только пользуемся его членами/методами?



Graphics - это namespace которому принадлежит класс TBitmap.

2) Как можно сделать чтоб фон рисунка был черным а не белым? Зарисовать все черными точками, а потом поверху рисовать своими серо-белыми? Или можно как то сразу с черным фоном создать?
В рез-те у меня должна получиться бело-серая картинка на черном фоне.


У класса TBitmap есть своя канва - так что ты свободно можешь использовать ВСЕ методы класса TCanvas для рисования в битмапе. Например - чтобы сделать битмапу с черным фоном:

Graphics::TBitmap *bmp=new Graphics::TBitmap();
bmp->PixelFormat=pf24bit;
bmp->Width=100;
bmp->Height=100;
bmp->Canvas->Brush->Color=clBlack;
bmp->Canvas->FillRect(Rect(0,0,bmp->Width,bmp->Height));
bmp->SaveToFile("c:\\test.bmp");
delete bmp;

ну или по другому:
for (int i=0;i<bmp->Height;i++) memset(bmp->ScanLine,0,bmp->Width*3);

Вобщем вот так.

1.8K
11 апреля 2004 года
Andreww
81 / / 02.01.2004
А можно ли посмотреть как-нибудь описание класса TBitmap в Билдере? Мне очень хочется сделать исходник не зависимый от среды разработки. Чтоб на чем угодно можно было скомпилить. В хидере <graphics.hpp>, который используется для работы с битмапом я нашел только обьявление разных там функций. А определений явно не нашел. Или определения в явном виде не доступны?
PS Кстати с праздником!
487
11 апреля 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by Andreww
А можно ли посмотреть как-нибудь описание класса TBitmap в Билдере? Мне очень хочется сделать исходник не зависимый от среды разработки. Чтоб на чем угодно можно было скомпилить. В хидере <graphics.hpp>, который используется для работы с битмапом я нашел только обьявление разных там функций. А определений явно не нашел. Или определения в явном виде не доступны?
PS Кстати с праздником!



Гы!
Для этих вещей треба Билдер ставить с опцией установки исходников VCL :) Тогда в папке билдера будет директорка Source в которой находишь паку VCL и ищещь в ней graphics.pas :) Токмо исходники на паскале :) А вообще советую тебе поискать сорцы для работы с битмапами в инете. Проще будет - сразу говорю. Сам формат не сложный - заголовок + RAW data. Ну есть там несколько заморочек - палитры например (кое где они идут в стандартном виде RGB - а кое где появляется еще и альфа-канал). Ну еще идиотский прикол что растр у битмапа перевернутый - идиотизм полнейший - тоесть скан-линии растра идут не снизу вверх, а сверху вниз. Ну и в некоторых случаях битмапы могут быть еще пожаты - но там стандартный RLE (кажется точно такой-же как и у PCX). Да, и еще тупорылые мелкомягкие сделали такое дебильное выравнивание (особенно чувствительно для 24 битных изображений), что вообще непонятно на какие границы они пытаются выровнять каждый скан - ну это уж вопрос к мыкрософту. Вобщем вот так.

1.8K
11 апреля 2004 года
Andreww
81 / / 02.01.2004
Да, у меня Билдер с исходниками установлен. Вот только не ожидал увидеть расширение PAS. Это они что сначала Дельфи пишут, а потом на нем Билдер делают? Вот почему релиз Билдера всегда с опозанием относително Дельфи :-( Позор однако.
10
12 апреля 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Andreww
Да, у меня Билдер с исходниками установлен. Вот только не ожидал увидеть расширение PAS. Это они что сначала Дельфи пишут, а потом на нем Билдер делают? Вот почему релиз Билдера всегда с опозанием относително Дельфи


Да, это политика Борланд. И еще одно соображение, почему надо писать на Дельфи, а не на Билдере ;)

1.8K
12 апреля 2004 года
Andreww
81 / / 02.01.2004
Цитата:
Originally posted by smartsoft

Да, это политика Борланд. И еще одно соображение, почему надо писать на Дельфи, а не на Билдере ;)


Не, надо переходить на альтернативные IDE, например CodeWarrior (вот только достать его - проблема), эта среда существует для всех ОСей (Win, MacOS, и скорее всего Linux), Языки: C++, Java;
Вот только взять и резко перепрыгнуть это конечно проблема. Я вот даже на VC не спешу перелазить.

10
12 апреля 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Andreww
Вот только взять и резко перепрыгнуть это конечно проблема. Я вот даже на VC не спешу перелазить.


Я к тому, что писать с использованием VCL надо на Дельфи. А без него - пожалуйста, выбирай что хочешь.

487
14 апреля 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by smartsoft

Я к тому, что писать с использованием VCL надо на Дельфи. А без него - пожалуйста, выбирай что хочешь.



Необязательно писать на дельфи. Builder весьма неплохо справляется с паскальным кодом :). Более того - при разработке прог на Билдере можно включать в проект паскалевские файлы - а в Дельфи сишный код включить не получится :). Да и C как язык помощнее Паскаля будет, хотя не скрою, в свое время писал исключительно на Паскале :)

10
14 апреля 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by ddnh_bc
Необязательно писать на дельфи. Builder весьма неплохо справляется с паскальным кодом :). Более того - при разработке прог на Билдере можно включать в проект паскалевские файлы - а в Дельфи сишный код включить не получится :).


Так в том-то и фишка, что для VCL Си не нужен, достаточно одного Дельфи. Поскольку весь VCL написан на Паскале, Си тут оказывается лишним, не побоюсь этого выражения. ;)

Цитата:
Originally posted by ddnh_bc
Да и C как язык помощнее Паскаля будет, хотя не скрою, в свое время писал исключительно на Паскале :)


А с этим никто не спорит. Все дело в перце.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог