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

Вниз

Преобразование форматов 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.004 c
2-1317566758
Reist
2011-10-02 18:45
2012.01.08
This form of method call only allowed for class methods


2-1317155348
Vladimir
2011-09-28 00:29
2012.01.08
Узнать какой из WebBrowser вызвал процедуру


15-1316925282
РВА
2011-09-25 08:34
2012.01.08
Подскажите по железу


15-1316204983
Юрий
2011-09-17 00:29
2012.01.08
С днем рождения ! 17 сентября 2011 суббота


2-1317495602
Leon-Z
2011-10-01 23:00
2012.01.08
Соединение с БД MySQL.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский