Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Изображение и WinAPI


Автор: Borland_Delphi_6 3.7.2004, 21:42
Решил попробовать написать что-нибудь на WinAPI. Форму создавать научился. Не подскажите ли, как теперь нарисовать на форме картинку из файла?

Автор: maxim1000 3.7.2004, 22:25
как-то надо было вывести картинку в консольном приложении, написал вот это (правда не на Delphi, а в VC, но это же WinAPI smile.gif )
Код
#define IMAGE_WIDTH   200
#define IMAGE_HEIGHT  150
#define WINDOW_WIDTH  (IMAGE_WIDTH+10)
#define WINDOW_HEIGHT (IMAGE_HEIGHT+30)

void LoadBMP(char * FileName,unsigned char *Destination,int Index)
{
 HBITMAP bmp;
 int x,y;
 HDC dc;
 int pixel;
 
 bmp=(HBITMAP)LoadImage(0,FileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
 dc=CreateCompatibleDC(0);
 SelectObject(dc,bmp);
 //for(y=IMAGE_HEIGHT*Index;y<IMAGE_HEIGHT*Index+IMAGE_HEIGHT;y++)
 for(y=Index;y<Index+IMAGE_HEIGHT;y++)
 {
   for(x=0;x<IMAGE_WIDTH;x++)
   {
     pixel=GetPixel(dc,x,y);
     *(Destination++)=GetRValue(pixel);
     *(Destination++)=GetGValue(pixel);
     *(Destination++)=GetBValue(pixel);
   }
 }
 DeleteDC(dc);
 DeleteObject(bmp);
}
HWND WindowForBMP;
void CreateBMPWindow()
{
 WindowForBMP=CreateWindow("STATIC","image",SS_BITMAP,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,0,0,0,0);
}
void ShowBMP(unsigned char *Image)
{
 HDC windowdc,memorydc;
 int x,y;
 short r,g,b;
 
 SetWindowPos(WindowForBMP,HWND_TOPMOST,300,300,WINDOW_WIDTH,WINDOW_HEIGHT,SWP_SHOWWINDOW | SWP_NOACTIVATE);
 windowdc=GetDC(WindowForBMP);
 memorydc=CreateCompatibleDC(windowdc);
 for(y=0;y<IMAGE_HEIGHT;y++)
 {
   for(x=0;x<IMAGE_WIDTH;x++)
   {
     r=*(Image++);
     g=*(Image++);
     b=*(Image++);
     SetPixel(windowdc,x,y,RGB(r,g,b));
   }
 }
 DeleteDC(memorydc);
 ReleaseDC(WindowForBMP,windowdc);
}

только не надо ругать меня за использование SetPixel - просто лень было разбираться с функциями типа GetDIBits
да и вообще все это написано на скорую руку...

Автор: Borland_Delphi_6 3.7.2004, 23:01
maxim1000
Спасибо конечно, но т.к. я VС в глаза не видел... sad.gif

Автор: maxim1000 4.7.2004, 12:10
Цитата
Спасибо конечно, но т.к. я VС в глаза не видел...

а вся суть в том, какие функции и с какими параметрами вызывать, а синтаксис вызова функции на C и Delphi довольно-таки похож...
а вообще для изучения WinAPI C очень не помешал бы
у меня у самого к Delphi довольно теплые чувства, но когда дело касается WinAPI тут я безоговорочно перехожу на C: все примеры обычно приводятся на нем...
---
ну, если попытаться переписать, получится что-то вроде этого:
Код
program Project1;
{$APPTYPE CONSOLE}
uses
 SysUtils,
 windows;
var
 WindowForBMP: HWND;
 bmp: HBITMAP;
 windowdc,memorydc:HDC;
begin
 WindowForBMP:=CreateWindow('STATIC','image',SS_BITMAP,0,0,210,180,0,0,0,0);
 bmp:=LoadImage(0,'qqq.bmp',IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
 SetWindowPos(WindowForBMP,HWND_TOPMOST,300,300,210,180,
              SWP_SHOWWINDOW or SWP_NOACTIVATE);
 windowdc:=GetDC(WindowForBMP);
 memorydc:=CreateCompatibleDC(windowdc);
 SelectObject(memorydc,bmp);
 BitBlt(windowdc,0,0,200,150,memorydc,0,0,SRCCOPY);
 DeleteDC(memorydc);
 ReleaseDC(WindowForBMP,windowdc);
 while true do;
end.

Автор: Borland_Delphi_6 4.7.2004, 12:47
maxim1000
Спасибо, попробую. Просто мне надо одну прогу на API написать, что бы она маленькая и шустрая была.

Автор: Borland_Delphi_6 4.7.2004, 13:13
maxim1000
Спасибо еще раз, уже кое-что получается biggrin.gif
Только я вот не пойму, зачем эта строчка:
Цитата
while true do;

Она привела мою прогу к зависанию, без нее все работает хорошо... smile.gif

Автор: maxim1000 4.7.2004, 19:51
Цитата
Только я вот не пойму, зачем эта строчка:
Цитата
while true do;

Она привела мою прогу к зависанию, без нее все работает хорошо...

когда консольное приложение закрывается, окно, которое оно создало уничтожается
цикл в конце предназначен, чтобы можно было успеть что-нибдуь увидеть
а когда надоест смотреть - Ctrl-C

Автор: Borland_Delphi_6 4.7.2004, 21:07
maxim1000
Ааа... Понятно. Просто я то твой код в неконсольное вставил smile.gif Но имхо, вместо цикла лучше юзать sleep(), т.к. такой цикл больше похож на глюк в программе smile.gif

Автор: RA 5.7.2004, 03:45
Вообще разрабатывать визуальные программы на вин апи это очень геморно, но если уж позарез нужен маленький размер приложения то можно написать его используя компонеты Kol и MCK
http://bonanzas.rinet.ru

Автор: dm9 5.7.2004, 17:08
RAdmin, да нет, для саморазвития полезно очень даже smile.gif Чтобы понять, как оно работает.

Автор: Borland_Delphi_6 5.7.2004, 21:50
maxim1000
А ты не подскажешь, как по событию таймера мне перерисовать пикчур? Таймер у меня уже есть.

Автор: dm9 5.7.2004, 23:10
Borland_Delphi_6, я ж тебе пример кидал. Смотри что там написано на обработке WM_PAINT. Подумать самому и почитать справочку тоже иногда полезно smile.gif

Автор: Borland_Delphi_6 6.7.2004, 00:16
dm9
Уже думал, так нифига не вышло sad.gif Лано, еще подумаю...

Автор: RA 6.7.2004, 01:51
Вообще из кода Maxi1000 надо убрать строчку
Код
{$APPTYPE CONSOLE}
и тогда всё поедет.

Автор: Borland_Delphi_6 6.7.2004, 12:59
RAdmin
Да я понимаю, не дурак smile.gif У меня и так все "едет", у меня щас немного другая проблема sad.gif

Автор: Borland_Delphi_6 6.7.2004, 17:28
Всем спасибо! Прога работает, даже почти без глюков! biggrin.gif Точнее, есть некоторое мерцание при перерисовке, но его практически не заметно rolleyes.gif Размер проги вышел в 13.5 кб user posted imageuser posted imageuser posted image

Автор: dm9 7.7.2004, 04:31
Покажи smile.gif

Автор: Borland_Delphi_6 7.7.2004, 11:40
dm9
Покожу, вот только ядро проги-то уже 20 кб, что есть гуд, а вот загружаемая картинка - 650 кб sad.gif Что есстественно не есть гуд при таком размере ядра программы sad.gif Щас над этим вопросом работаю. notify.gif

Автор: Borland_Delphi_6 9.7.2004, 14:56
Показываю... из-за того, что заметил глюк. Хорошо проявляется на маленькой пикчуре. Если не сложно, посмотрите файлик (около 25 кб).
-- Аттач удален smile.gif --

Автор: maxim1000 9.7.2004, 17:25
похоже, некорректно стирается предыдущее изображение
правда, вылечить это можно даже без изменения кода smile.gif
надо сделать по границе рисунка рамку цвета фона (т.е. черного)
я попробовал - хвост исчезает smile.gif

Автор: Borland_Delphi_6 9.7.2004, 21:55
maxim1000
Э-э-э... Че-то я не въехал, так ведь на рисунке фон черный весь... Или как?

Автор: maxim1000 10.7.2004, 00:37
да не совсем...
насколько я понял передвижение картинки происходит так: она просто рисуется на новом месте (если старое изображение и стирается, то, как мне кажется, там засел глюк)
дело в том, что в правой верхней части картинки цветная (нечерная) область подходит вплотную к границе, поэтому, когда картинка сдвигается влево-вниз (насколько я понял, это тот случай, когда глюк заметен больше всего), эта область остается нестертой.
чтобы проиллюстрировать это можно попробовать следующее (именно это я имел в виду, когда сказал, что это можно вылечить без изменения кода):
1. увеличить размеры рисунка на два пиксела с каждой стороны
2. исходный рисунок расположить по середине получившегося
3. закрасить границы черным
(короче, взять рисунок в черную рамку)
я попробовал - все нормально...
P.S.
правда правильнее было бы назвать это не лечением, а залечиванием: стоит увеличить шаг продвижения картинки и рамку придется увеличивать...

Автор: Borland_Delphi_6 10.7.2004, 13:47
maxim1000
Ок, увеличу пикчур.

Автор: Borland_Delphi_6 10.7.2004, 20:30
Вроде все работает smile.gif maxim1000, спасибо! thumbs-up.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)