Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.01.08;
Скачать: CL | DM;

Вниз

Преобразование форматов TBitmap   Найти похожие ветки 

 
я   (2011-09-28 01:21) [0]

Есть такой код:
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-битный, но в нем дополнительно добавлен четвертый канат (альфа-канал), содержащий дополнительную информацию о прозрачности каждой точки.

Вопрос - можно ли как то отменить прозрачность точки, и добится того, чтобы цвет этой точки был всегда постоянный вне зависимости от изменений фона или такое не возможно?


 
antonn ©   (2011-09-28 01:38) [1]


> Вопрос - можно ли как то отменить прозрачность точки, и
> добится того, чтобы цвет этой точки был всегда постоянный
> вне зависимости от изменений фона или такое не возможно?
>

в интернете гораздо больше вопросов как вообще заставить работать этот альфаканал :) т.е. по умолчанию он есть, но GDI в дельфи его обнуляет. Если не использовать функции альфабленда то этот четвертый байт прозрачности не мешает.

да, кстати, это чего?
tBmp2.Handle:=hbmp;


 
antonn ©   (2011-09-28 01:38) [2]


> т.е. по умолчанию он есть

для pf32bit


 
я   (2011-09-28 01:51) [3]


> PrintWindow(HWND, hSrcDC, 0);


раньше я делал так PrintWindow(HWND, tBmp2.Canvas.Handle, 0);
но этот метод че то как то тоже глючил. Т.е. во втором параметре передается хендл, и после копирования в него помещается хендл на изображение. т.е. после копирования этот хендл насколько я понимаю запихивают в тот битмап де оно должно матеарилезоваться.  Почему сделано именно так я и сам хз.

Вообщем ошибки 2 либо неверный формат, потому что почему то поменялось на пфдевайс, либо про скан лайн если не поменялось (


 
я   (2011-09-28 01:53) [4]

First chance exception at $75A09673. Exception class EInvalidGraphicOperation with message "Scan line index out of range".


 
я   (2011-09-28 02:03) [5]

hBmp := CreateCompatibleBitmap(hDC1, r.right - r.left, r.bottom - r.top);

эта функция создает битмап совместимый с DC. и возвращает хендл на него. Я так понимаю что создает он его вовсе не с тем форматом, который я выше описал. И когда я бмп2 присвою этот хендл он начнет ссылаться на этот битмап нетого формата......но что с этим делать....


 
я   (2011-09-28 02:12) [6]

меняешь формат, получаешь это:

First chance exception at $75A09673. Exception class EInvalidGraphicOperation with message "Scan line index out of range".

Вообще все происходит в момент запуска приложения, и при получении хендла вместо окна еще отображается заставка и она собственно и скриншотится, а потом разворачивается окно. В то время как я продолжаю оперировать со скриншотом заставки. Хз как это может на что то влиять. Но я уже не знаю что и думать. Кроме того если окно уже запущено, т.е. заставка уже прошла и я тогда запускаю эту процедуру, то ошибки нет.


 
я   (2011-09-28 02:14) [7]

собственно мне бы хотелось чтобы этот момент просто проходил в холостую, но надежно определить что окно уже нормально нарисовалось у меня не вышло, поэтому вот.....


 
Омлет ©   (2011-09-28 08:32) [8]

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 08:38) [9]

> "Scan line index out of range"

Это ошибка модуля UQPixels. Возникает, если высота битмапа меньше 2.


 
я   (2011-09-28 08:50) [10]


> function MyPrintWindow(Wnd: HWND; Bmp: TBitmap): boolean;


раньше я так и делал, за исключением лока. В результате у меня временами получались белые скриншоты...поэтому стал делать как в первом посте...


 
Омлет ©   (2011-09-28 09:01) [11]

А теперь делай с локом.


 
я   (2011-09-28 18:49) [12]

эх точно, перелопатил пару сотен строк и обнаружил таки, что в одном месте получался битмап нулевого размера...


 
я   (2011-09-28 19:22) [13]

Вообщем проблемма ясна  и грустна.

При появлении окна меняется хендл. Т.е. по хендлу полученомму при старте приложения уже ничего нет. И моим способом получается скрин нулевого размера, а способом Омлета получается белый скрин.

Заново искать хендл в каждой процедуре че то не тянет, но похоже выхода нет.



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

Текущий архив: 2012.01.08;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.008 c
15-1316692399
Очень Злой
2011-09-22 15:53
2012.01.08
помогите найти заразу


15-1316169795
Dimka Maslov
2011-09-16 14:43
2012.01.08
Пятничная задачка


15-1316348444
alexdn
2011-09-18 16:20
2012.01.08
Php bb форумный движек и спам боты


15-1316636981
Юрий
2011-09-22 00:29
2012.01.08
С днем рождения ! 22 сентября 2011 четверг


15-1316723402
Юрий
2011-09-23 00:30
2012.01.08
С днем рождения ! 23 сентября 2011 пятница