На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
Страницы: (3) 1 [2] 3  все  ( Перейти к последнему сообщению )  
> Высота, ширина, цвет точки HBITMAP-а , без модуля Graphics
    Цитата AndNot @
    Если есть желание разбираться, то увидишь, про что я все это время толковал

    Спасибо, не нужно :) У меня на сайте тоже есть пример работы :) 32-битные битмапы действительно не содержат палитру, но данные храняться в виде RGBQUAD. Собственно вот пример смешения цветов двух битмапов, где DIBColorSrc указатель на область данных о пикселях загруженного битмапа (надеюсь все в курсе5 что внутри иконки лежат битмапы? :) ):
    ExpandedWrap disabled
      procedure MakeAlphaBlend(DIBColorSrc, DIBDest: PRGBQuad;
        const DIBColorSrcSize: Integer); assembler;
      asm
       
        // Запоминаем значение регистров в стеке
       
        push eax
        push ebx
        push ecx
        push edx
        push edi
        push esi
       
        mov  esi, DIBColorSrc       // карта цветов иконки
        mov  edi, DIBDest           // карта цветов фона
        //mov  ecx, DIBColorSrcSize   // размер массивов (приходит в ECX сам по себе)
       
        shr  ecx, 2                 // размер элемента массива равен четырем,
                                    // поэтому поправим счетчик цикла
       
      // -----------------------------------------------------------------------------
       
      @loop:
       
        // цвета представленны следующим образом
        // [esi]  = синий
        // [esi + 1]  = зеленый
        // [esi + 2] = красный
        // [esi + 3]  = альфа канал
       
        mov  al, [esi + 3]          // читаем значение альфа канала
        cmp  al, 0                  // есть ли изображение иконки в данном пикселе?
        jne  @paint_full
       
        add  esi, 4                 // если нет - берем следующий элемент
        add  edi, 4
        loop @loop
        jmp  @done
       
      // -----------------------------------------------------------------------------
       
      @paint_full:
        cmp  al, 255                // Смотрим интенсивность цвета
        jne  @paint_alpha
       
        mov  eax, [esi]             // Данный пиксель полностью заполнен цветом иконки
        mov  [edi], eax             // копируем его целиком
       
        add  esi, 4                 // берем следующий элемент
        add  edi, 4
        loop @loop
        jmp  @done
       
      // -----------------------------------------------------------------------------
       
      @paint_alpha:
       
        // присутствует альфаканал
        
        xor  ebx, ebx
        call @make_alpha            // микшируем синий цвет
        inc  ebx
        call @make_alpha            // микшируем зеленый цвет
        inc  ebx
        call @make_alpha            // микшируем красный цвет
       
        add  esi, 4                 // берем следующий элемент
        add  edi, 4
        loop @loop
        jmp  @done
       
      // -----------------------------------------------------------------------------
       
      @make_alpha:
       
        // функция смешивает два цвета в зависимости от значения EBX,
        // которое указывает какой именно брать байт из RGB
       
        xor  eax, eax
        xor  edx, edx
        mov  al, byte [edi + ebx]   // берем цвет приемника
        mov  dl, byte [esi + 3]     // берем значение альфаканала
        not  dl                     // значение альфаканала вычитаем из 255
        mul  dl                     // умножаем на получившееся значение
        or   dl, $FF
        div  dl                     // делим на 255
       
        mov  byte [edi + ebx], al   // запоминаем первый результат
       
        xor  eax, eax
        xor  edx, edx
        mov  al, byte [esi + ebx]   // берем цвет источника
        mov  dl, byte [esi + 3]     // берем значение альфаканала
        mul  dl                     // умножаем на значение альфаканала
        or   dl, $FF
        div  dl                     // делим на 255
       
        xor  edx, edx
        mov  dl, byte [edi + ebx]   // читаем первый результат
        add  ax, dx                 // к нему прибавляем второй результат
        mov  byte [edi + ebx], al   // сумму помещаем обратно
       
        ret
       
      // -----------------------------------------------------------------------------  
       
      @done:
       
        // Восстановление значений регистров из стека
        
        pop  esi
        pop  edi
        pop  edx
        pop  ecx
        pop  ebx
        pop  eax
      end;
      А еще мне не понятна область lpvBits если само содержимое битмапа копируется, посмотрел в описании функции:
      function GetDIBits(DC: HDC; Bitmap: HBitmap; StartScan, NumScans: UINT; Bits: Pointer; var BitInfo: TBitmapInfo; Usage: UINT): Integer; stdcall;
      Я как понял это указатель на буфер цветов, а вот как его объявлять не пойму никак...

      И еще, при считывании размеров:
      ExpandedWrap disabled
         var
          memDC: HDC;
          hBkgnd: HBITMAP;
          BMI: TBitmapInfo;
        begin
          hBkgnd := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
         
          memDC := GetDC(0);
          GetDIBits(memDC, hBkgnd, 0, 0, nil, BMI, DIB_RGB_COLORS);
          ReleaseDC(0, memDC);
        end;

      BMI.bmiHeader.biWidth и BMI.bmiHeader.biHeight (пускай хоть и отрицательный) не правильно определяются ширина с высотой, т.е. Реальные размеры картинки 283 x 149, если посмотреть в свойствах файла в виндовсе, а у меня определяется как 70 x 5...

      Что-то я не пойму никак что не так...
        Цитата Rouse_ @
        32-битные битмапы действительно не содержат палитру, но данные храняться в виде RGBQUAD

        А есть еще 24-х и 16-ти битные. На них твой пример и загнется ;)
        Цитата Rouse_ @
        надеюсь все в курсе5 что внутри иконки лежат битмапы?

        Там еще и маски есть ;)
        Цитата Rouse_ @
        У меня на сайте тоже есть пример работы

        И на основании этого ты и сделал вывод что в bmiColors[] хранится цвет точек? Этот пример совершенно не показывает структуру BMP ;)
        Цитата Dmitry_177 @
        А еще мне не понятна область lpvBits

        Я так понял. Это буфер для образа рисунка, т.е. если нужно преобразовать битмап не в контекст устройства(DC) а в буфер, то в этом параметре передаешь на нее указатель. После чего сможешь легко определить любой пиксель ;) Собственно из-за этого параметра и весь сыр-бор.
        Цитата Dmitry_177 @
        Я как понял это указатель на буфер цветов, а вот как его объявлять не пойму никак...

        GetMem()
        Цитата Dmitry_177 @
        Реальные размеры картинки 283 x 149, если посмотреть в свойствах файла в виндовсе, а у меня определяется как 70 x 5...

        Ты сам должен корректно заполнять этот заголовок, прежде чем скормишь его GetDIBits.
        И кстати, вместо GetDC(0) попробуй так:
        ExpandedWrap disabled
            memDC := CreateCompatibleDC(0);
            GetDIBits(memDC, hBkgnd, 0, 0, nil, BMI, DIB_RGB_COLORS);
            DeleteDC(memDC);
          Цитата AndNot @
          А есть еще 24-х и 16-ти битные. На них твой пример и загнется

          Конечно, но для этого есть другая часть примера, я же сказал где посмотреть :)
          Цитата AndNot @
          Там еще и маски есть

          Есть, но если ты знаешь формат, то можешь удивиться - с альфой они не используются :)
          Цитата AndNot @
          И на основании этого ты и сделал вывод что в bmiColors[] хранится цвет точек? Этот пример совершенно не показывает структуру BMP

          Этот пример абсолютно наглядно показывает структуру 32-битных растров :)
          Что еще имеем сказать? :)
            Dmitry_177, вот загрузчик битмапов, по идее должен все загружать. Так проще разобраться, а то мы что то не в ту степь поперли :lol:
            ExpandedWrap disabled
              Type
                PSprite = ^TSprite;
                TSprite = record
                  Width : Integer;
                  Height: Integer;
                  Buffer: ^Byte;
                end;
               
              function ConvImage(ImgName: String): PSprite;
              var
                Bitmap: TBitmap;
                Buff  : PSprite;
                Info  : TBitmapInfo;
                MemDC : HDC;
              begin
                Bitmap := TBitmap.Create;
                Bitmap.LoadFromFile(ImgName);
              // формируем заголовок
                with Info.bmiHeader do
                  begin
                    FillChar(Info, SizeOf(TBitmapInfo), 0);
                    biSize := SizeOf(TBitmapInfoHeader);
                    biWidth := Bitmap.Width;   // можешь поиграться с размерами
                    biHeight := Bitmap.Height; // получаемого изображения
                    biPlanes := 1;             // всегда 1
                    biCompression := BI_RGB;   // нет никакой компрессии данных
                    biBitCount := 24;          // пиксели будут в формате RGBTRIPLE
                                               // для RGBQUAD поставь 32
                    GetMem(Buff, SizeOf(TSprite));
                    Buff^.Width := biWidth;
                    Buff^.Height:= biHeight;
                    GetMem(Buff^.Buffer,(biWidth*biHeight) * (biBitCount shr 3));
                    MemDC := CreateCompatibleDC(0);
                    GetDIBits(MemDC,Bitmap.Handle, 0, biHeight, Buff^.Buffer, Info, DIB_RGB_COLORS);
                    DeleteDC(MemDC);
                  end;
                Bitmap.Free;
                ConvImage := Buff;
              end.

            Возвращает именно растр. Его формат указан в biBitCount.
            Извини за возможные очепятки и некоторое несоответствие типов, дельфи в отказ пошел, похоже система последние дни доживает :(
            Цитата Rouse_ @
            с альфой они не используются

            Да они вообще в принципе не нужны ;)
            Цитата Rouse_ @
            Этот пример абсолютно наглядно показывает структуру 32-битных растров

            Ладно завязываем. Разговор то поначалу пошел про поле bmiColors[].
              Цитата AndNot @
              Ладно завязываем. Разговор то поначалу пошел про поле bmiColors

              Поддерживаю :yes:
                ExpandedWrap disabled
                  Bitmap.LoadFromFile(ImgName);
                  ...
                  biWidth := Bitmap.Width;   // можешь поиграться с размерами
                  biHeight := Bitmap.Height; // получаемого изображения

                Это же битмап из модуля Graphics я как понял, а мне без него нужно...
                  Цитата Dmitry_177 @
                  Это же битмап из модуля Graphics я как понял, а мне без него нужно...

                  А это не важно. Главное получить хэндл загруженного в память битмапа. Например так:
                  Замени
                  ExpandedWrap disabled
                      Bitmap: TBitmap;

                  на
                  ExpandedWrap disabled
                      Bitmap: Handle; // или HWND

                  Затем загрузи его с помощью какой либо функции:
                  LoadBitmap - если из файла
                  LoadResource - из ресурсов
                  etc.
                  И полученный хендл передаешь вместо Bitmap.Handle;
                    а HBITMAP разве не хэндл? Загружаю его из файла:
                    hBkgnd := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

                    а как же быть с Bitmap.Width; Bitmap.Height;?
                      Цитата Dmitry_177 @
                      а HBITMAP разве не хэндл?

                      Извини, забыл сказать. Хэндлом может считаться любой DWORD.
                      Цитата Dmitry_177 @
                      Загружаю его из файла:
                      hBkgnd := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

                      Почему бы и нет? А почему не хочешь LoadBitmap использовать?
                      Цитата Dmitry_177 @
                      а как же быть с Bitmap.Width; Bitmap.Height;?

                      Для определения ширины и высоты исходного битмапа вроде подходит функция GetBitmapDimensionEx(Handle: HBITMAP; var p: TPoint);

                      PS: Сообщи о результатах ;) Я сам то еще не попробовал.
                        Так не работает почему-то...
                        ExpandedWrap disabled
                          var
                            BmpSize: SIZE;
                            hBmp: HBITMAP;
                          begin
                            hBmp := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
                            GetBitmapDimensionEx(hBmp, BmpSize);


                        BmpSize.cx и BmpSize.cy равны нулю...
                          >GetBitmapDimensionEx(hBmp, BmpSize);
                          >BmpSize.cx и BmpSize.cy равны нулю...
                          Так а какая ошибка возвращается от GetBitmapDimensionEx?
                          И загружается ли сам Битмап?
                            Битмап загружается, все правильно, потому что пробовал потом выводить его все выводится...

                            А вот так правильно определяются размеры, но только этот способ наверно медленнее чем с GetBitmapDimensionEx или нет?
                            ExpandedWrap disabled
                              var
                                DIBS: DIBSECTION;
                              begin
                                hBmp := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
                               
                                GetObject(hBmp, SizeOf(DIBS), @DIBS);
                               
                                W := DIBS.dsBm.bmWidth;
                                H := DIBS.dsBm.bmHeight;
                              end;
                              Цитата Dmitry_177 @
                              BmpSize.cx и BmpSize.cy равны нулю...

                              Нда, в справе в самом конде есть замечательное примечание - она возвращает размер установленный с помощью SetBitmapDimensionEx. Так что не катит.
                              Цитата Dmitry_177 @
                              А вот так правильно определяются размеры, но только этот способ наверно медленнее чем с GetBitmapDimensionEx или нет?

                              Все равно ничего другого не остается :( Разве что самому считывать заголовок, но зачем, если он уже считан? Уж лучше так оставь.
                                Dmitry_177, верно, я именно так и делаю. Только не вздумай получать от туда BPP(bmBitsPixel)! Так как, как я уже писал она вернёт BPP текущего Device Context, а не то как записано в фаиле и не то, как вернётся из GetDIBits. Вот для этого уже придётся действительно читать Хеадер фаила.
                                Получив здесь не достающую мне информацию, я пришёл к выводу, что надо бы вообще написать отдельный модуль (свой) для работы с Битмапом. Как бы я не любил WinAPI, с битмапом там не всё так хорошо как хотелось бы.. (ИМХО).
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 [2] 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0619 ]   [ 16 queries used ]   [ Generated: 25.04.24, 06:51 GMT ]