![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Преобразование форматов TBitmap
я © (2011-09-28 01:21:00)Есть такой код:
tBmp2 := TBitmap.Create;
tBmp2.PixelFormat := pf24bit;
GetWindowRect(HWND, r);
hDC1:= GetDC(HWND);
hSrcDC:=CreateCompatibleDC(hDC1);
hBmp := CreateCompatibleBitmap(hDC1, r.right - r.left, r.bottom - r.top);
SelectObject(hSrcDC, hBmp);
PrintWindow(HWND, hSrcDC, 0);
BitBlt(
hDC1,
0,
0,
r.right - r.left,
r.bottom - r.top,
hSrcDC,
0,
0,
SRCCOPY);
tBmp2.Handle:=hbmp;
tbmp2.SaveToFile('E:\testscreen.bmp');
Затем полученый tbmp2 передается в другую функцию, где есть такой код:
var
x:cardinal;
y:cardinal;
QP1: TQuickPixels;
Pixel:cardinal;
Intensity:byte;
res:boolean;
begin
QP1 := TQuickPixels.Create;
QP1.Attach(tbmp2);
Проблемма в том, что несмотря на то, что я в начале уставновил формат
на tBmp2.PixelFormat := pf24bit;
После копирования, если глянуть в отладчике он уже: pfDevice. Причем сохраненная картинка цветная и потери качества не видно.
Если после сохранения вызвать опять tBmp2.PixelFormat := pf24bit;
то QP1.Attach(tbmp2 ) будет орать про Scane Line out of index или что то в этом роде. А если вообще ничего не вызывать, то будет орать что формат не поддерживается.
Вопрос че за дела? Почему поменялся формат? и почему его нельзя вернуть назад? и как сделать все хорошо?
2) Пока я об этом гуглил наткнулся та такой текст:
Режим 32 бит похож на 24-битный, но в нем дополнительно добавлен четвертый канат (альфа-канал), содержащий дополнительную информацию о прозрачности каждой точки.
Вопрос - можно ли как то отменить прозрачность точки, и добится того, чтобы цвет этой точки был всегда постоянный вне зависимости от изменений фона или такое не возможно?
я (2011-09-28 19:22:00) [1]Вообщем проблемма ясна и грустна.
При появлении окна меняется хендл. Т.е. по хендлу полученомму при старте приложения уже ничего нет. И моим способом получается скрин нулевого размера, а способом Омлета получается белый скрин.
Заново искать хендл в каждой процедуре че то не тянет, но похоже выхода нет.
я (2011-09-28 18:49:00) [2]эх точно, перелопатил пару сотен строк и обнаружил таки, что в одном месте получался битмап нулевого размера...
Омлет (2011-09-28 09:01:00) [3]А теперь делай с локом.
я (2011-09-28 08:50:00) [4]
> function MyPrintWindow(Wnd: HWND; Bmp: TBitmap): boolean;
раньше я так и делал, за исключением лока. В результате у меня временами получались белые скриншоты...поэтому стал делать как в первом посте...
Омлет (2011-09-28 08:38:00) [5]> 'Scan line index out of range'
Это ошибка модуля UQPixels. Возникает, если высота битмапа меньше 2.
Омлет (2011-09-28 08:32:00) [6]
function PrintWindow(HWND:HWND;hdcBlt:HDC;nFlags:DWORD):BOOL; stdcall; external 'user32.dll';
function MyPrintWindow(Wnd: HWND; Bmp: TBitmap): boolean;
var
R: TRect;
begin
GetWindowRect(Wnd, R);
Bmp.Width := R.Right - R.Left;
Bmp.Height := R.Bottom - R.Top;
Bmp.Canvas.Lock;
try
Result := PrintWindow(Wnd, Bmp.Canvas.Handle, 0);
finally
Bmp.Canvas.Unlock;
end;
end;
procedure TForm1.btn1Click(Sender: TObject);
var
tBmp: TBitmap;
begin
tbmp := TBitmap.Create;
try
tBmp.PixelFormat := pf24bit;
if MyPrintWindow(Handle, tBmp) then
tbmp.SaveToFile('c:\1.bmp');
finally
tbmp.Free;
end;
end;
я (2011-09-28 02:14:00) [7]собственно мне бы хотелось чтобы этот момент просто проходил в холостую, но надежно определить что окно уже нормально нарисовалось у меня не вышло, поэтому вот.....
я (2011-09-28 02:12:00) [8]меняешь формат, получаешь это:
First chance exception at $75A09673. Exception class EInvalidGraphicOperation with message 'Scan line index out of range'.
Вообще все происходит в момент запуска приложения, и при получении хендла вместо окна еще отображается заставка и она собственно и скриншотится, а потом разворачивается окно. В то время как я продолжаю оперировать со скриншотом заставки. Хз как это может на что то влиять. Но я уже не знаю что и думать. Кроме того если окно уже запущено, т.е. заставка уже прошла и я тогда запускаю эту процедуру, то ошибки нет.
я (2011-09-28 02:03:00) [9]hBmp := CreateCompatibleBitmap(hDC1, r.right - r.left, r.bottom - r.top);
эта функция создает битмап совместимый с DC. и возвращает хендл на него. Я так понимаю что создает он его вовсе не с тем форматом, который я выше описал. И когда я бмп2 присвою этот хендл он начнет ссылаться на этот битмап нетого формата......но что с этим делать....
я (2011-09-28 01:53:00) [10]First chance exception at $75A09673. Exception class EInvalidGraphicOperation with message 'Scan line index out of range'.
я (2011-09-28 01:51:00) [11]
> PrintWindow(HWND, hSrcDC, 0);
раньше я делал так PrintWindow(HWND, tBmp2.Canvas.Handle, 0);
но этот метод че то как то тоже глючил. Т.е. во втором параметре передается хендл, и после копирования в него помещается хендл на изображение. т.е. после копирования этот хендл насколько я понимаю запихивают в тот битмап де оно должно матеарилезоваться. Почему сделано именно так я и сам хз.
Вообщем ошибки 2 либо неверный формат, потому что почему то поменялось на пфдевайс, либо про скан лайн если не поменялось (
antonn (2011-09-28 01:38:00) [12]
> Вопрос - можно ли как то отменить прозрачность точки, и
> добится того, чтобы цвет этой точки был всегда постоянный
> вне зависимости от изменений фона или такое не возможно?
>
в интернете гораздо больше вопросов как вообще заставить работать этот альфаканал :) т.е. по умолчанию он есть, но GDI в дельфи его обнуляет. Если не использовать функции альфабленда то этот четвертый байт прозрачности не мешает.
да, кстати, это чего?
tBmp2.Handle:=hbmp;
antonn (2011-09-28 01:38:00) [13]
> т.е. по умолчанию он есть
для pf32bit