Bazaprogram.ru

Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Delphi bitblt пример

Delphi bitblt пример

Подскажите пожалуйста пример работы функции BitBlt (нужен код функции).


Mihey ( 2003-02-02 20:49 ) [1]

function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: Longint): Bool;

Контекст устpойства, пpинимающего каpту бит. Имеется ввиду контекст (handle) канвы (canvas), на которую копируется изображение. Например, если изображение выводится на форму, то указывается контекст канвы формы, а именно: Form.Canvas.Handle. Для изображений TBitMap аналогично: BitMap.Canvas.Handle, но никак не BitMap.Handle.

Координаты верхнего левого угла прямоугольной области, в которую выводится изображение. Проще говоря, координаты изображения.

Ширина и высота прямоугольной области, в которую выводится изображение. Если хотите вывести изображение целиком, то указывайте его настоящие размеры (постоянные или определённые по свойствам Width и Height). Вообще, X, Y, Width, Height вместе похожи на структуру TRect, которая используется в определении той же области вывода изображения в функции Draw объекта TCanvas.

Контекст устpойства, из котоpого копиpуется каpта бит, или нуль для pастpовой опеpации только на DestDC. Здесь, аналогично DestDC, указывается Handle объекта TCanvas изображения, которое будет скопировано на (именно «на», а не «в», т.к. речь идёт о копировании по битам) DestDC. В то же время, вы можете указать в этом параметре нуль, и на DestDC в зависимости от растровой операции (см. ниже) выведется прямоугольная область указанных в параметрах Width и Height размеров.

Веpхний левый угол SrcDC. Поясняю: прямоугольник размера W >
Rop

Одна из констант теpнаpных pастpовых опеpаций: Blackness, DSTInvert, MergeCopy, MergePaint, NotSrcCopy, NotSrcErase, PatCopy, PatInvert, PatPaint, SrcAnd, SrcCopy, SrcErase, SrcInvert, SrcPaint, Whiteness. Этот параметр отвечает за то, как SrcDC будет спроецировано DestDC. SrcCopy выполняет пpостое копиpование из источника в назначение.


reticon ( 2003-02-02 23:41 ) [2]


Mihey ( 2003-02-03 00:12 ) [3]

Нет, не совсем так. TPicture может загружать JPEG файлы, так как использует TGraphic. Загрузив JPEG картинку в TPicture ты теперь можешь обратиться к канве свойства Bitmap:

MyPic := TPicture.Create;
MyPic.LoadFromFile(«SomeJPG.jpg»);
SrcDC := MyPic.Bitmap.Canvas.Handle;

Ведь всё равно все форматы в загруженном виде хранятся в BMP.


reticon ( 2003-02-03 03:13 ) [4]

.
var MyPic: TPicture;
.
MyPic := TPicture.Create;
MyPic.LoadFromFile(«SomeJPG.jpg»);
SrcDC := MyPic.Bitmap.Canvas.Handle;
.
Не знаю, но почему-то этот способ не хочет работать 🙁

Работает только через TBitmap, (SomeBMP.bmp)
а если через TJPEGImage — тоже лажа какая-то


Mihey ( 2003-02-03 21:28 ) [5]

Ссори, забыл добавить — надо в Uses написать модуль jpeg. Иначе не работает:

Uses Windows, SomeShit, Jpeg, Messages;


reticon ( 2003-02-04 08:05 ) [6]

Я же говорю что не в этом проблема, Жпег я подключал.
Проблема, мне кажется в использовании JPEG с TPicture.
Да и еще, насколько я знаю, жпег, по-моему, не в тему в TGraphic,
там ведь только bmp, wmf, и ico.


Mihey ( 2003-02-04 20:22 ) [7]

Да, пока ещё в Delphi с JPEG не гладко. Но вот выход:

procedure TForm1.Button1Click(Sender: TObject);
var
jp: TJpegImage; //Незабудь про «jpeg» в «uses».
Pic: TBitMap;
begin
jp := TJpegImage.Create;
Pic := TBitMap.Create;
jp.LoadFromFile(«C:logo.jpg»);
Pic.Assign(jp);
jp.Free;
BitBlt(Canvas.Handle, 0, 0, Pic.Width, Pic.Height, Pic.Canvas.Handle, 0, 0, SrcCopy);
end;

Этот код работает. А ещё я подумал, что если открывать изображения методами TImage, то Bitmap будет содержать желаемое изображение.

Delphi bitblt пример

Возвращаемое значение
Отлично от нуля, если функция успешна, иначе 0.

Параметры
x
Определяет логическую x-координату левого верхнего угла прямоугольника адресата.
y
Определяет логическую y-координату левого верхнего угла прямоугольника адресата.
nWidth
Определяет ширину (в логических модулях) прямоугольника адресата и исходного точечного рисунка.
nHeight
Определяет высоту (в логических модулях) прямоугольника адресата и исходного точечного рисунка.
pSrcDC
Указатель на объект CDC, который идентифицирует контекст устройства из которого точечный рисунок будет скопирован. Должно быть NULL если dwRop определяет растровую операцию, которая не включает источник.
xSrc
Определяет логическую x-координату левого верхнего угла исходного точечного рисунка.
ySrc
Определяет логическую y-координату левого верхнего угла исходного точечного рисунка.
dwRop
Определяет растровую операцию, которую нужно выполнить. Коды растровой операцией определяют, как GDI объединяет цвета в операциях вывода, которые включают текущую кисть, возможный исходный точечный рисунок, и точечный рисунок адресата. Следующие коды растровой операции списков для dwRop и их описаний:

  • BLACKNESS — Растровая карта выводиться черным.
  • DSTINVERT — Инвертирует точечный рисунок адресата.
  • MERGECOPY — Объединяет образец и исходный точечный рисунок, использующий Булевый и (AND) оператор.
  • MERGEPAINT — Объединяет инвертированный исходный точечный рисунок с точечным рисунком адресата используя Булевый или (OR) оператор.
  • NOTSRCCOPY — Копирует инвертированный исходный точечный рисунок адресату.
  • NOTSRCERASE — Инвертирует результат объединения адресата и исходных точечных рисунков, используя Булевый и(AND) оператор.
  • PATCOPY — Копирует образец к точечному рисунку адресата.
  • PATINVERT — Объединяет точечный рисунок адресата с образцом, используя Булевый оператора XOR.
  • PATPAINT — Объединяет инвертированный исходный точечный рисунок с образцом, используя Булевый или(OR) оператор. Объединяет результат этой операции с точечным рисунком адресата используя Булевый или (OR) оператор.
  • SRCAND — Объединяет пиксели адресата и исходных точечных рисунков, используя Булевый и (AND) оператор.
  • SRCCOPY — Копирует исходный точечный рисунок к точечному рисунку адресата.
  • SRCERASE — Инвертирует точечный рисунок и объединяет результат с исходным точечным рисунком, используя Булевый и (AND) оператор.
  • SRCINVERT — Объединяет пиксели адресата и исходных точечных рисунков, используя Булевый оператора XOR.
  • SRCPAINT — Объединяет пиксели адресата и исходных точечных рисунков, используя Булевый или (OR) оператор.
  • WHITENESS — Вся растровая карта белая.
Читать еще:  Снять защиту с xls файла

Замечания
Копирует точечный рисунок от исходного контекста устройства до этого текущего контекста устройства.
Прикладная программа может выравнивать окна или клиентские области на границах байта, чтобы гарантировать, что операции Bitblt происходят на выровненных байтом прямоугольниках. (Устновите CS_BYTEALIGNWINDOW или CS_BYTEALIGNCLIENT, когда Вы регистрируете классы окна.)
Операции пересылки строки битов на выровненных байтом прямоугольниках значительно быстрее чем операции Bitblt на прямоугольниках, которые — не выровненный байт. Если Вы хотите определять стили класса типа выравнивания байта для вашего собственного контекста устройства, Вы будете должны регистрировать класс окна скорее чем доверять MFC. Используйте глобальную функцию AfxRegisterWndClass.
GDI трансформирует nWidth и nHeight, один раз, используя контекст устройства адресата, и один раз, используя исходный контекст устройства. Если возникающие в результате протяженность не соответствуют, GDI использует функцию Windows StretchBlt, чтобы сжимать или растягивать исходный точечный рисунок по мере необходимости.
Если адресат, источник, и точечные рисунки образца не имеет того же самого цветного формата, функция Bitblt преобразовывает источник и точечные рисунки образца, чтобы соответствовать адресату. Приоритетные и фоновые цвета точечного рисунка адресата используются в преобразовании.
Когда функция Bitblt преобразовывает одноцветный точечный рисунок в цвет, она устанавливает белые биты (1 к фоновым цветным и черным битам 0 к цвету символа). Приоритетные и фоновые цвета контекста устройства адресата используются. Чтобы преобразовывать цвет в одноцветный, пересылка строки битов устанавливает пиксели, которые соответствуют фоновому цвету к белому, и устанавливает все другие пиксели к черному. Пересылка строки битов использует приоритетные и фоновые цвета цветного контекста устройства, чтобы преобразовать от цвета до одноцветного.
Обратите внимание, что не все контексты устройства поддерживают BitBlt. Чтобы проверять, поддерживает ли данный контекст устройства, BitBlt, используйте GetDeviceCaps функцию с индексом индекс RASTERCAPS.

BitBlt течет (решено)

Доброе время суток форумчане. Мне стыдно от того что не могу разобраться сам, но
вот такой вот простой код, у меня дает утечку памяти:

Почему ты думаешь, что у тебя утечка? Диспетчер задач любит врать.
Прокрути это в цикле 100500 раз, если память после роста в какой-то момент на какой-то цифре остановится, значит, утечки нет.

  • RadianTOR
  • Постоялец

TarasB
кручу по таймеру 5 раз в секунду, и за 3-4 минуты 4 мегабайта прирост. Причем ежесекундно по 12-20 килобайт.
fsmoke
Чтоб release и free всегда выполнялись.

  • kipar
  • Участник

—-
Кстати, можно сделать ReportMemoryLeaksOnShutdown:=True чтобы убедиться течет ли память выделяемая дельфевским менеджером памят. Но это только в Delphi 2010+

  • RadianTOR
  • Постоялец

kipar
> Кстати, можно сделать ReportMemoryLeaksOnShutdown:=True чтобы убедиться течет
> ли память выделяемая дельфевским менеджером памят. Но это только в Delphi 2010+
Если закомментить строку BitBlt, то утечки нет (

  • master-sheff
  • Постоялец

radiantor
У меня утечки нет.
Другого кода точно нет? уменьши проект до минимума.

  • laMer007
  • Удалён

radiantor
> Если закомментить строку BitBlt, то утечки нет (
Слышал похожую историю. Исправили игрой с флагами CS_OWNDC или CS_CLASSDC. Если других идей нет, то побалуйтесь.
Надеюсь bmp.Free; только в отладочных целях уничтожает результат работы BitBlt?

  • RadianTOR
  • Постоялец

master-sheff
> У меня утечки нет.
Блин, неужели у меня дельфя кривая. На какой системе тестировал?
Щас уже пробовал в пустой проект вставить, таймер не ставил, тупо цикл по кнопке запускается.

laMer007
> Надеюсь bmp.Free; только в отладочных целях уничтожает результат работы BitBlt?
да.

  • clc
  • Постоялец

ты хочешь порисовать на экране?

в справке говориться что DC(0) это экран, но не сказано release(0, DC(0)) это он же.
может поможет release(GetDesktopWindow(void), DC(0))

зы наверно имелся в виду весь регион окна

  • igo
  • Забанен

а шо? низя его один раз взять и много раз пользоваться.
это не шутки. это же цельный ДС. с ним надо осторожней. можешь все дс доступные расплескать. это даже перезагрузкой не лечиться, придется видеокарту менять и колесо в мышке.

  • master-sheff
  • Постоялец

radiantor
> На какой системе тестировал?
Windows 8 x64
Delphi XE3

  • fsmoke
  • Постоялец

radiantor
> Чтоб release и free всегда выполнялись.
radiantor
> Блин, неужели у меня дельфя кривая. На какой системе тестировал?

1) эээ. раз Вы так рассуждаете — видимо вы слабо понимаете то, что пытаетесь написать

2) bitblt течь не может

3) выкладывайте исходники

  • fsmoke
  • Постоялец

master-sheff
> Windows 8 x64
> Delphi XE3

ух ты, не уверен, что найду — но на 7ке могу глянуть

а кстати на 7ке не пробывали??

  • kipar
  • Участник

Delphi XE3, Win7, не течет. Но если пользоваться кодом #8, то может возникнуть впечатление что течет, т.к. на кнопку можно нажать много раз подряд, до завершения ее цикла. Если все эти слипы и ProcessMessages убрать, то не течет.

Читать еще:  Правила именования css

Delphi bitblt пример

В данном коде есть 2 проблемы(возможно больше ):

1:При совместном использовании функций CreateCompatibleBitmap и LoadBitmapW(LoadBitmap) происходит ошибка времени выполнения. Хотя по отдельности никаких проблем нет все компилируется и запускается.

2:Данный код не выводит ничего на дисплей. В чем здесь дело? Чего не хватает? (Rectangle вставил как раз чтобы проверить не в Bitmap у ли дело. Выясняется что нет.)

Перед заданием вопроса упорно гуглил, но нашел лишь подобные примеры. Объясните пожалуйста что я не так делаю. Заранее благодарен!

1. OXPEHOMETP , 21.08.2008 16:40
Проблемы:

  1. Совместно использовать CreateCompatibleBitmap и LoadBitmap нельзя и не нужно. Либо то, либо другое.
  2. Вывести прямоугольник во временный контекст у вас не получилось потому, что такой контекст умеет рисовать только в запиханную в него посредством вызова SelectObject bitmap’у (в момент создания такого контекста посредством CreateCompatibleDC в него по умолчанию «запихнута» монохромная картинка размером в один пиксел — и это четко сказано в документации).
  3. В обработчике отрисовки (OnPaint) обычно пользуются всё же CPaintDC, а не CClientDC. И тому есть причины.

И ещё — зачем вы здесь используете new? Мало того, что можно прекрасно обойтись локальными переменными (см. пример ниже), так вы ещё и не удаляете созданное.

В общем, вот вам код, рисующий картинку.

2. Shtirlitz2008 , 21.08.2008 23:13
Спасибо большое за помощь! Но вот возник еще один вопрос.Я пробую делать так:

При любом перемещении все мое изображение начинает мерцать, перерисовываться. Однако, если посмотреть на стандартные игры windows(всякий там сапер, карты, и т.д.) то при перетаскивании окна никакой перерисовки не происходит. Каким образом это реализовано там? Я пытался рисовать изображение в обработчиках других событий и конструкторе CMFC6View, однако там ничего не рисуется. Подскажите пожалуйста как избавиться от проблемы связанной с перерисовкой.

3. vertur , 21.08.2008 23:58
Используйте отрисовку в back буфер а потом флуште на экран через BitBlt — мерцания не будет, либо запретите перерисовку в момент перетаскивания. Это классика.

ЗЫ. И еще — а нахера рисовать в цикле одно и тоже ? Зачем процессор и прочие хардваре нагружать ? Перерисовывать надо лишь то, что изменило свое состояние (ИМХО) и обратите внимание на BeginPaint/EndPaint. Прежде чем задавать здесь вопросы продумайте хорошенько структуру своего приложения и не забудте про WM_ERASEBKGND — оно вносит свою лепту в дело мерцания.

4. Shtirlitz2008 , 22.08.2008 00:12
1 Каким образом я из CompatibleDC выбиру ту область, которую надо перерисовать?
2 Что значит back буфер? Имеется ввиду то что у меня sourceDC?
3 Как запретить перерисовку в момент перетаскивания?
5. vertur , 22.08.2008 00:13
Shtirlitz2008
1. см BeginPaint/EndPaint — эти функции обновляют маску областей которые надо перерисовать, маска уже привязана к hDC.
2. попробуйте перевести, дословно. Метод этот обычно используется во всяких FPS приложениях/гамах
3. можно пофантазировать — например булевым флагом
6. Shtirlitz2008 , 22.08.2008 01:18
Я пытаюсь создать CompatibleDC в методах vo />nBeginPrinting(CDC *pDC, CPrintInfo* /*pInfo*/), CMFC6View::CMFC6View(), и используя BeginPaint и EndPaint сделать BitBlt на targetDC в OnPaint. Однако сколько вариантов я не перепробовал, так ни один и не заработал. Не могли бы вы пояснить работу этих функций? И еще как можно создать совместимый контекст в методе отличном от onPaint, и потом лишь использовать его там?
7. vertur , 22.08.2008 02:08
так. всегда говорил что MFC — это жесть, это жестокая жесть, это отвратительная весчь.

Мы сейчас говорим о выводе на дисплей — так ? причем тут nBeginPrinting ? — там свои тонкости есть, оставте это пока, контекст принтера и контекст дисплея — это совсем совсем разные весчи. Ваша беда в том, что вы принялись за MFC не поняв простого WinAPI, а MFC очень завязана на элементы WinAPI — Многие классы этой библиотеки — просто обертки над функциями WinAPI. За более детальной инфой читайте MSDN.

Итак, насколько я понимаю, вы хотите нарисовать в окошке несколько битмапов.

Согласно принципам WinAPI вы должны обработать сообщение WM_PAINT для своего окошка (MFC скрывает часть этого процеса но не всю, обработчиком WM_PAINT — является метод OnPaint)
ok, что-бы не заставлять систему рисовать лишнее в должны (согласно MSDN) заключить тело обработчика в своеобразные скобки (если угодно — аналог OpenGl’ских Glbegin Glend) — BeginPaint, EndPaint. Эти функции сконфигурируют маску, которая выделит в hDC те области которые надо проапдейтить — т.е области в которых по мнению винды информация могла исказится, например за счет наложения другого окна.

Создадть контекст совместимый с дисплейным — не просто. а ОЧЕНЬ просто из любой точки оконного приложения — читайте MSDN

ЗЫ: Окончательный код в студию было бы желательно, ибо непонятно что и как вы используете.

ЗЫ2: Оболочкой над HDC, реализующей BeginPaint/EndPaint при создании/уничтожении является (насколько я понимаю) CPaintDC

ЗЫ3: Вкратце. В винде есть понятие контекста графического устройства. По большому счету это некоторая структура, которая хранит состояние графического устройства (текущую битмапу, текущую кисть, цвет и толщину линии и т.д.) Что конкретно за устройство скрывается под HDC — никто не должен знать: это может быть принтер, может быть дисплей или плотер. Таким образом обеспечивается совместимость всех устройств отображения. Для работы с контекстами есть ряд функций, в частности
CreateCompatibleDC. Эта функция создает контекст совместимый с имеющимся, по умолчанию (для параметра NULL) берется контекст дисплея. Далее, согласно MSDN, все Create..DC функции создают контекст с текущей чернобелой битмапой (это «подложка» на которой происходит рисование), размерами 1×1. Если вы хотите использовать другую текущую битмапу — её надо выбрать с помощью SelectObject(HBITMAP), при этом надо не забывать что эта функция возвращает хендл прошлого текущего (для данной HDC) обьекта, которые неплохо было установить назад перед удалением контекста.

Неужели так трудно прочитать об этом в MSDNе ?

ЗЫ4: Если содержимое окна статическое — можете перехватить WM_ERASEBKGRND и. ничего внутри не делать (вернуть TRUE, либо указать при регистрации оконного класа нулевой хендл для HBRUSH которая используется для заливки фона — фон перестанет перерисовываться перед посылкой сообщения WM_PAINT.

ЗЫ5: Насчет создания совместимого с дисплейным контекста в методе nBeginPrinting — ЗАЧЕТ! А вы не пробовали подумать над тем когда этот метод вызывается ? Спорю на ясчиг пива что в вашем создаваемом hDC — мусор.

ЗЫ6: Насчет ясщига погорячился. чувствуется приближение пятницы.

8. OXPEHOMETP , 22.08.2008 08:34
Shtirlitz2008: Вдогонку, обо всём по порядку:

    Мерцание при перетаскивании. Если вы создавали приложение AppWizard’ом (или как оно там щас называется), поищите во всём коде слова CS_HREDRAW и CS_VREDRAW. Вот пример из только что созданного проекта:

9. Shtirlitz2008 , 22.08.2008 13:28
1 Хм. А по поводу wtl можно по-подробнее? Что и с чем едят?
2 Я, конечно, на счет WinAPI слаб, но тут вот какое дело. Серьезно углубляться в WinAPI желания все же нет, пару игрушек простеньких я на API писал, с битмапами правда не работал. Но когда цель стоит в написании прикладного софта, неужели необходимо вдаваться в подробности API? (Что такое WM_PAINT, и как происходит обработка сообщений я знаю, проблема скорее в связи MFC и WinAPI, ибо я имею достаточно мутное представление о том как классы MFC связаны с API? Т.е. если даже я знаю как что либо менять в WinAPI проге, то с классами возникает путаница. В API все ясно где какая мессага, а тут еще думай что в конструктор что в OnCreate. )
10. vertur , 22.08.2008 17:11
WTL это Windows Template Library — набор шаблонов классов оберток над WinAPI, вообщем достаточно неплохая весчь. Но от необходимости изучать WinAPI она вас не избавит.

Если не хотите разбираться с WinAPI, то тогда есть смысл использовать библиотеку Qt.
Там своя философия (и надо сказать очень хорошая), полное абстрагирование от системных API,
да и програмы окажутся переносимыми между Win/*Nix.

11. Shtirlitz2008 , 22.08.2008 17:55
А с VS2008 она совместима?

цитата: А с VS2008 она совместима?

Хм, вопрос не понял немного. WTl — это набор заголовков с шаблонами, вообще (ИМХО) любая библиотека с исходным кодом совместима со всем, вопрос весь в умелых руках. Под MSVC2008 я с ней не работал, под MSVC60/MSVC2005/evc30/evc40 всё ок.

12. vertur , 23.08.2008 18:26
13. Shtirlitz2008 , 23.08.2008 21:50
Я имел ввиду Qt? Ее реально в VS2008 использовать?
14. vertur , 23.08.2008 22:03
Shtirlitz2008
Опс, пардон. Не понял что вопрос про Qt.

Qt, которая может собираться под MSVC, насколько я знаю, существует только в «платном» или ознакомительном виде (потом при запуске начинает такое окошко — напоминалку выдавать). В своё время хотел сделать свой порт для MSVC из того что есть — но руки так и не дошли.

Та Qt, которая «бесплатная» она для GNU GCC, но вы погуглите, наверняка для MSVC есть готовый самодельный порт.

Во всяком случае всё (сорцы и демки тоже) можно скачать с сайта TrollTech.

15. AzikAtom , 23.08.2008 23:24
Shtirlitz2008
Зачем все это добро перерисовывать в OnPaint?
Рисуйте в глобальный bitmap в тех функциях, где происходит изменение изображения (OnCreate, ход. ), а в OnPaint только перерисовать эту bitmap на DC своего окна. При этом никакого мерцания не будет.
В этом случае ничего мерцать не будет, даже если не выключать отрисовку фона. Хотя, лучше выключить, наверное
ЗЫ. После обновления (изменения) рисунка не забыть перекинуть bitmap на экран.
16. Shtirlitz2008 , 23.08.2008 23:48
vo />nPaint()
<
CPaintDC targetDC(this);
targetDC.BitBlt(0,0,70*8+5,70*8+5,&TempSourceDC,0,0,SRCCOPY);
>

Вот это мой onPaint. При изменении размеров окна и при его перетасиквании мерцания заметны и раздражают. Так что это не помогает. Насчет выключения WM_ERASEBKGND, то тут тоже проблема.

BOOL CMFC6View: nEraseBkgnd(CDC *pDC)
<
return TRUE;
>*/

Ссылка на основную публикацию
Adblock
detector