Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Вниз

Помогите с картинкой   Найти похожие ветки 

 
Андрей Валенинов   (2004-08-03 13:36) [0]

Уважаемые мастера, я хочу сделать программу на день рождения папе и в день рождения запустить у него на компьютере. Я хочу чтобы у него на рабочем столе появился букет цветов и надпись под ним.
Мне вот дали код который делает программу такой как исходная картинка, но он не работает, а я исправить его не могу так как для меня он очень сложен. Я только начал изучать язык.
Пожалуйста помогите исправить ошибки.

Я понимаю конечно что просьба немного глупая.

unit RgnUnit;
interface
uses
 Windows, SysUtils, Classes;
function CreateBitmapRgn(DC : hDC; Bitmap: hBitmap; TransClr: TColorRef): hRgn;

implementation
//создает регион из растра Bitmap для DC с удалением цвета TransClr
//внимание! TColorRef и TColor не одно и тоже.
//Для перевода используется функция ColorToRGB().
function CreateBitmapRgn(DC: hDC; Bitmap: hBitmap; TransClr: TColorRef): hRgn;
var
 bmInfo: TBitmap;               // структура BITMAP WinAPI
 W, H: Integer;                 // высота и ширина растра
 bmDIB: hBitmap;                // дискрептор независимого растра
 bmiInfo: BITMAPINFO;           // структура BITMAPINFO WinAPI
 lpBits, lpOldBits: PRGBTriple; // указатели на структуры RGBTRIPLE WinAPI
 lpData: PRgnData;              // указатель на структуру RGNDATA WinAPI
 X, Y, C, F, I: Integer;        // переменные циклов
 Buf: Pointer;                  // указатель
 BufSize: Integer;              // размер указателя
 rdhInfo: TRgnDataHeader;       // структура RGNDATAHEADER WinAPI
 lpRect: PRect;                 // указатель на TRect (RECT WinAPI)
begin
 Result:=0;
 //если растр не задан, выходим
 if Bitmap=0 then
   Exit;
 //узнаем размеры растра
 GetObject(Bitmap, SizeOf(bmInfo), @bmInfo);
 //используя структуру BITMAP
 W:=bmInfo.bmWidth;
 H:=bmInfo.bmHeight;
 //определяем смещение в байтах
 I:=(W*3)-((W*3) div 4)*4;
 if I<>0 then
   I:=4-I;
 //Пояснение: растр Windows Bitmap читается снизу вверх, причем каждая строка
 //дополняется нулевыми байтами до ее кратности 4.
 //для 32-х битный растров такой сдвиг делать не надо.
 //заполняем BITMAPINFO для передачи в CreateDIBSection
 bmiInfo.bmiHeader.biWidth:=W;            // ширина
 bmiInfo.bmiHeader.biHeight:=H;           // высота
 bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
 bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель
 bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компрессии
 bmiInfo.bmiHeader.biSizeImage:=0;        // размер не знаем, ставим в ноль
 bmiInfo.bmiHeader.biXPelsPerMeter:=2834; // пикселей на метр, гор.
 bmiInfo.bmiHeader.biYPelsPerMeter:=2834; // пикселей на метр, верт.
 bmiInfo.bmiHeader.biClrUsed:=0;          // палитры нет, все в ноль
 bmiInfo.bmiHeader.biClrImportant:=0;     // то же
 bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структруы
 bmDIB:=CreateDIBSection(DC, bmiInfo, DIB_RGB_COLORS,
 Pointer(lpBits), 0, 0);
 //создаем независимый растр WxHx24, без палитры, в указателе lpBits получаем
 //адрес первого байта этого растра. bmDIB - дискрептор растра
 //заполняем первые шесть членов BITMAPINFO для передачи в GetDIBits
 bmiInfo.bmiHeader.biWidth:=W;            // ширина
 bmiInfo.bmiHeader.biHeight:=H;           // высота
 bmiInfo.bmiHeader.biPlanes:=1;           // всегда 1
 bmiInfo.bmiHeader.biBitCount:=24;        // три байта на пиксель
 bmiInfo.bmiHeader.biCompression:=BI_RGB; // без компресси
 bmiInfo.bmiHeader.biSize:=SizeOf(bmiInfo.bmiHeader); // размер структуры
 GetDIBits(DC, Bitmap, 0, H-1, lpBits, bmiInfo, DIB_RGB_COLORS);
 //конвертируем исходный растр в наш с его копированием по адресу lpBits
 lpOldBits:=lpBits; //запоминаем адрес lpBits
 //первый проход - подсчитываем число прямоугольников, необходимых для
 //создания региона
 C:=0; //сначала ноль
 //проход снизу вверх
 for Y:=H-1 downto 0 do
 begin
   X:=0;
   //от 0 до ширины-1
   while Xdo
   begin
     //пропускаем прзрачный цвет, увеличивая координату и указатель
     while (RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
     lpBits.rgbtBlue)=TransClr) and (Xdo
     begin
       Inc(lpBits);
       X:=X+1;
     end;
     //если нашли не прозрачный цвет, то считаем, сколько точек в ряду он идет
     if RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
     lpBits.rgbtBlue)<>TransClr then
     begin
       while (RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
       lpBits.rgbtBlue)<>TransClr) and (Xdo
       begin
         Inc(lpBits);
         X:=X+1;
       end;
       //увиличиваем счетчик прямоугольников
       C:=C+1;
     end;
   end;
   //ряд закончился, необходимо увеличить указатель до кратности 4
   PChar(lpBits):=PChar(lpBits)+I;
 end;
 lpBits:=lpOldBits; //восстанавливаем значение lpBits
 //Заполняем структуру RGNDATAHEADER
 rdhInfo.iType:=RDH_RECTANGLES;     // будем использовать прямоугольники
 rdhInfo.nCount:=C;                 // их количество
 rdhInfo.nRgnSize:=0;               // размер выделяем памяти не знаем
 rdhInfo.rcBound:=Rect(0, 0, W, H); // размер региона
 rdhInfo.dwSize:=SizeOf(rdhInfo);   // размер структуры
 //выделяем память для струтуры RGNDATA:
 //сумма RGNDATAHEADER и необходимых на прямоугольников
 BufSize:=SizeOf(rdhInfo)+SizeOf(TRect)*C;
 GetMem(Buf, BufSize);
 //ставим указатель на выделенную память
 lpData:=Buf;
 //заносим в память RGNDATAHEADER
 lpData.rdh:=rdhInfo;
 //Заполдяенм память прямоугольниками
 lpRect:=@lpData.Buffer; //первый прямоугольник
 for Y:=H-1 downto 0 do
 begin
   X:=0;
   while Xdo
   begin
     while (RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
     lpBits.rgbtBlue)=TransClr) and (Xdo
     begin
       Inc(lpBits);
       X:=X+1;
     end;
     if RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
     lpBits.rgbtBlue)<>TransClr then
     begin
       F:=X;
       while (RGB(lpBits.rgbtRed, lpBits.rgbtGreen,
       lpBits.rgbtBlue)<>TransClr) and (Xdo
       begin
         Inc(lpBits);
         X:=X+1;
       end;
       lpRect^:=Rect(F, Y, X, Y+1); //заносим координаты
       Inc(lpRect); //переходим к следующему
     end;
   end;
   PChar(lpBits):=PChar(lpBits)+I;
 end;
 //после окночания заполнения структуры RGNDATA можно создавать регион.
 //трансформации нам не нужны, ставим в nil, указываем размер
 //созданной структуры и ее саму.
 //создаем регион
 Result:=ExtCreateRegion(nil, BufSize, lpData^);
 //теперь структура RGNDATA больше не нужна, удаляем
 FreeMem(Buf, BufSize);
 //созданный растр тоже удаляем
 DeleteObject(bmDIB);
end;
end.


 
Profi ©   (2004-08-03 14:58) [1]

Не парься! Нарисуй bmp"шку и натени на рабочий стол функцией systemparametersinfo.


 
Андрей Валенинов   (2004-08-03 15:21) [2]

для Profi

Да в том то и дело что мне не на рабочий стол надо - а мне надо именно форму такую с надписью под букетом. На рабочий стол он мне запретил картинки ставить - говорит систему это перегружает.


 
parovoZZ ©   (2004-08-03 16:09) [3]

Не думаю, что смена картинки на столе перегрузит систему больше, чем выше приведённый код. Скорее даже наоборот.
По сабжу: что именно и где не работает? Как пользуешься вышеприведённой функцией? Я делал тоже самое, но тело функции проще, потому как параметры картинки известны.


 
parovoZZ ©   (2004-08-03 16:09) [4]

Не думаю, что смена картинки на столе перегрузит систему больше, чем выше приведённый код. Скорее даже наоборот.
По сабжу: что именно и где не работает? Как пользуешься вышеприведённой функцией? Я делал тоже самое, но тело функции проще, потому как параметры картинки известны.


 
Андрей Валенинов   (2004-08-03 16:41) [5]

для parovoZZ ©

У меня папа говорит что на рабочем столе не должно быть никогда никаких картинок, потому что картинки на рабочий стол придумали ставить уроды и изза картинок компьютер повиснит, точнее будет перегружаться. А мои программы которые я делаю по учебнику папа разрешает запускать и говорит что гипертреидинг делает так что сколькобы программ не работало одновременно он не повиснит.
У меня нету функции простее чем эта. Я изучаю книжку "Delphi для чайников". А там не учат делать то что мне нужно. (мне 13 лет и я занимаюсь делфи только два месяца и поэтому еще не умею ничего крутова).
Если вы не можите помочь исправить ошибки, немогли бы вы
написать вашу простую функию и расказать как ей пользоваться.


 
Кириешки ©   (2004-08-03 16:46) [6]

"картинки на рабочий стол придумали ставить уроды и изза картинок компьютер повиснит"

Хотел бы я пообщаться с твоим папой }:-#


 
parovoZZ ©   (2004-08-03 16:46) [7]

По поводу картинок я промолчу.


 
Кириешки ©   (2004-08-03 16:57) [8]

Я твоему папе не букет цветов бы нарисовал с надписью внизу, а просто одну надпись - "Good Lamed - Dead Lamer"


 
Mihey_temporary ©   (2004-08-03 18:26) [9]

Похоже на развод. Если процессор с Hyperthreading"ом, то наверное и Doom 3 пойдёт.

А по делу. http://www.torry.net/pages.php?id=94


 
parovoZZ ©   (2004-08-03 20:18) [10]

Держи то, что обещал:


//Создай новый проект, удали из него форму и Unit1. Нижеследующий код вставь в проект (предварительно удали всё из проекта).

program Region;

uses
 windows,
 messages;

const
Picture = "Ball_orig.bmp";//Файл с картинокй, обязательно должен быть с расширением *.BMP (без компрессии), должен лежать в той же папке, где эта прога. В противном случае здесь должен быть прописан полный путь к файлу.

var
WClass        : TWndClassEx;
Handle        : HWND;         //
Msg           : TMsg;
Image         : HBitmap;
PictureDC     : HDC;
Height, Width : Byte;

//Почти тоже самое, только намного короче
function CreateRgn (DC : HDC) : HRGN;
var
Rgn                        : HRGN;
x, y                       : integer;
ConsecutivePixels          : integer;
CurrentPixel, CurrentColor : Cardinal;
Transparent                : Cardinal;
begin

Result := CreateRectRgn (0, 0, Width, Height);
Transparent := GetPixel (DC, 0, 0);//Цвет отрезаемых пикселей устанавливается по крайнему верхнему левому пикселю (можно изменить на любой другой). Регион не может поделить вырезаемую картинку на части, поэтому она должна быть цельной!!!
for y := 0 to Height - 1 do
 begin
  CurrentColor := GetPixel (DC, 0, y);
  ConsecutivePixels := 1;
  for x := 0 to Width - 1 do
   begin
    CurrentPixel := GetPixel (DC, x, y);
    if CurrentColor = CurrentPixel then inc (ConsecutivePixels)
     else
      begin
       if CurrentColor = Transparent then
        begin
         Rgn := CreateRectRgn (x - ConsecutivePixels, y, x, y + 1);
         CombineRgn (Result, Result, Rgn, RGN_DIFF);
         DeleteObject (Rgn);
        end;
      CurrentColor := CurrentPixel;
      ConsecutivePixels := 1;
     end;
    end;

    if (CurrentColor = Transparent) and (ConsecutivePixels > 0) then
     begin
      Rgn := CreateRectRgn (x - ConsecutivePixels, y, x, y + 1);
      CombineRgn (Result, Result, Rgn, RGN_DIFF);
      DeleteObject (Rgn);
     end;
  end;
end;

procedure LoadPicture;
var
DC : HDC;
BM : BitMap;

begin
Image := LoadImage (0, picture, Image_Bitmap, 0, 0, LR_LOADFROMFILE or LR_CREATEDIBSECTION);
DC := GetDC (Handle);
PictureDC := CreateCompatibleDC (DC);
SelectObject (PictureDC, Image);
GetObject (Image, SizeOf (BitMap), @BM);
Height := BM.bmHeight;//Иногда возникают ошибки с определением размера картинки, если такое случится, придётся прописывать вручную
Width := BM.bmWidth;
ReleaseDC (Handle, DC);
end;

function WindowProc (Handle : THandle; Msg : Integer; Wparam : Wparam; Lparam : Lparam) : LResult; stdcall;
var
 DC        : HDC;
 Rgn       : HRGN;
 Rect      : TRect;

begin

Result := 0;

case Msg of
                WM_Create   : begin//Вырезаем регион при создании формы
                               if GetTopWindow(0) <> Handle then
                                  SetWindowPos(handle, HWND_TOPMOST, 100, 100, Width, Height,
                                                    swp_nomove Or swp_nosize Or swp_showwindow);
                                  DC := GetDC (Handle);
                                  Rgn := CreateRgn (PictureDC);
                                  SetWindowRgn (Handle, Rgn, true);
                                  BitBlt (DC, 0, 0, Width, Height, PictureDC, 0, 0, SrcCopy);
                                  DeleteObject (Rgn);
                                  ReleaseDC (Handle, DC);
                             end;

            WM_LButtonDown : SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);//Перемещаем окно за любое место))

    WM_WINDOWPOSCHANGING
    or WM_WINDOWPOSCHANGED : begin//При перемещениях формы перерисовываемся
                               DC := GetDC (Handle);
                               BitBlt (DC, 0, 0, Width, Height, PictureDC, 0, 0, SrcCopy);
                               ReleaseDC (Handle, DC);
                             end;
                               
            WM_RButtonDown : SendMessage (Handle, WM_Destroy, 0, 0);//Клик правой кнопкой мышки приводит к уничтожению окна

                WM_Destroy : begin//Уничтожаем окно
                               PostQuitMessage (0);
                               Exit;
                             end;

     else Result := DefWindowProc (Handle, Msg, Wparam, Lparam);
end;

end;

begin

FillChar (WClass, SizeOf (WClass), 0);
WClass.cbSize := SizeOf (WClass);
WClass.hCursor := LoadCursor (0, IDC_HAND);
WClass.hInstance := hInstance;
WClass.lpszClassName := "Region";
WClass.lpfnWndProc := @WindowProc;
RegisterClassEx (WClass);
LoadPicture;

Handle := CreateWindowEx (WS_EX_ToolWindow, "Region", "", WS_Popup,
                           0, 0, Width, Height, 0, 0, hInstance, nil);


ShowWindow (Handle, SW_SHOW);

While GetMessage (Msg, 0, 0, 0) do
   begin
     DispatchMessage (Msg);
   end;

if Image > 0 then DeleteObject (Image);
if PictureDC > 0 then DeleteDC (PictureDC);
end.



PS: © За последствия работы этого кода я никакой ответственности не несу. Используй на свой страх и риск. На пне 4 и ХР это всё работает на ура.

//Редкий русский программист знает ещё и родной язык. Почему так?


 
Андрей Валенинов   (2004-08-03 21:38) [11]

Спасибо вам большое Мастер parovoZZ !!!



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.044 c
1-1097310723
Kolan
2004-10-09 12:32
2004.10.31
Access violation и chart


3-1096325902
Mizanthrope
2004-09-28 02:58
2004.10.31
Сортировка записей в таблице


14-1097675011
matt
2004-10-13 17:43
2004.10.31
Программирование микрокроцессоров


14-1097551845
pkm
2004-10-12 07:30
2004.10.31
Виртуальный диск.


14-1096930070
NiceManiac
2004-10-05 02:47
2004.10.31
Ламоразмы и обшибки.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский