int xs=640;
int ys=480;
BYTE *buf=new BYTE[xs*ys*3];
HDC mdc=...;
BITMAP mbm=...;
BITMAPINFO bi;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biClrImportant=0;
bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biHeight=ys;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biSizeImage=0;
bi.bmiHeader.biWidth=xs;
GetDIBits(mdc, mbm, 0, ys, buf, &bi, DIB_RGB_COLORS);
Помогите с BitMap
Я делал так
HDC ScreenDC = GetDC(0);
HDC MemDC=CreateCompatibleDC(ScreenDC);
HBITMAP Bitmap=CreateCompatibleBitmap(ScreenDC,1024,768 );
SelectObject(MemDC,Bitmap);
BitBlt(MemDC,0,0,1024,768,ScreenDC,0,0,SRCCOPY);
BITMAP bm;
GetObject(Bitmap, sizeof(BITMAP), &bm);
ReleaseDC(0, ScreenDC);
Что я делал не так???
И как надо сделать правильно???
Цитата:
Originally posted by lai
Как получить указатель на Bitmap зная hDC (DYSPLAY), т.е. затолкать рабочий стол в массив.
Я делал так
Что я делал не так???
И как надо сделать правильно???
Как получить указатель на Bitmap зная hDC (DYSPLAY), т.е. затолкать рабочий стол в массив.
Я делал так
HDC ScreenDC = GetDC(0);
HDC MemDC=CreateCompatibleDC(ScreenDC);
HBITMAP Bitmap=CreateCompatibleBitmap(ScreenDC,1024,768 );
SelectObject(MemDC,Bitmap);
BitBlt(MemDC,0,0,1024,768,ScreenDC,0,0,SRCCOPY);
BITMAP bm;
GetObject(Bitmap, sizeof(BITMAP), &bm);
ReleaseDC(0, ScreenDC);
Что я делал не так???
И как надо сделать правильно???
Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Graphics::TBitmap* dbmp = new Graphics::TBitmap();
dbmp->Width = Screen->Width;
dbmp->Height = Screen->Height;
HDC hdc = GetDC(0);
BitBlt(dbmp->Canvas->Handle, 0, 0, Screen->Width, Screen->Height, hdc, 0, 0, SRCCOPY);
ReleaseDC(0, hdc);
dbmp->SaveToFile("DesktopImage.bmp");//<-здесь
delete dbmp;
}
{
Graphics::TBitmap* dbmp = new Graphics::TBitmap();
dbmp->Width = Screen->Width;
dbmp->Height = Screen->Height;
HDC hdc = GetDC(0);
BitBlt(dbmp->Canvas->Handle, 0, 0, Screen->Width, Screen->Height, hdc, 0, 0, SRCCOPY);
ReleaseDC(0, hdc);
dbmp->SaveToFile("DesktopImage.bmp");//<-здесь
delete dbmp;
}
Necro666, что-то я попробовал сделать как ты писал, но что-то ничего не получилось, в итоге на форме был нарисован черный квадрат :) а не копия Desktop. Ниже идет код того что я написал. Похоже там чего-то не хватает. Только не знаю чего :(
Код:
void __fastcall TForm1::Button6Click(TObject *Sender){
int xs=Screen->Width, ys=Screen->Height;
int LineWidth=(((xs*24-1)>>5)+1)<<2; //Выравнивание до слова
BYTE *buf=new BYTE[LineWidth*ys];
HDC ScreenDC=GetDC(NULL);
HBITMAP Bitmap=CreateCompatibleBitmap(ScreenDC,xs,ys);
BITMAPINFO bi={sizeof(BITMAPINFOHEADER), xs, ys, 1, 24, BI_RGB, 0, 0, 0, 0, 0, NULL};
int res=GetDIBits(ScreenDC, Bitmap, 0, ys, buf, &bi, DIB_RGB_COLORS);
//----- только для проверки того что получили в buf
Graphics::TBitmap *bmp=new Graphics::TBitmap();
bmp->Width=xs; bmp->Height=ys; bmp->PixelFormat=pf24bit;
for(int y=0; y<ys; y++) memcpy(bmp->ScanLine[y], &buf[y*LineWidth], LineWidth);
Canvas->Draw(0, 0, bmp);
delete bmp;
//-----
ReleaseDC(0, ScreenDC);
delete[] buf;
}
int xs=Screen->Width, ys=Screen->Height;
int LineWidth=(((xs*24-1)>>5)+1)<<2; //Выравнивание до слова
BYTE *buf=new BYTE[LineWidth*ys];
HDC ScreenDC=GetDC(NULL);
HBITMAP Bitmap=CreateCompatibleBitmap(ScreenDC,xs,ys);
BITMAPINFO bi={sizeof(BITMAPINFOHEADER), xs, ys, 1, 24, BI_RGB, 0, 0, 0, 0, 0, NULL};
int res=GetDIBits(ScreenDC, Bitmap, 0, ys, buf, &bi, DIB_RGB_COLORS);
//----- только для проверки того что получили в buf
Graphics::TBitmap *bmp=new Graphics::TBitmap();
bmp->Width=xs; bmp->Height=ys; bmp->PixelFormat=pf24bit;
for(int y=0; y<ys; y++) memcpy(bmp->ScanLine[y], &buf[y*LineWidth], LineWidth);
Canvas->Draw(0, 0, bmp);
delete bmp;
//-----
ReleaseDC(0, ScreenDC);
delete[] buf;
}
Код:
//obtain the GDI screen surface:
HDC dc=GetDC(0);
int xs=GetDeviceCaps(dc,HORZRES);
int ys=GetDeviceCaps(dc,VERTRES);
//obtain offscreen buffer & create copy to operate on it:
HDC mdc=CreateCompatibleDC(dc);
HBITMAP mbm=CreateCompatibleBitmap(dc,xs,ys);
HBITMAP backbm=SelectObject(mdc,mbm);
BitBlt(mdc,0,0,xs,ys,dc,0,0,SRCCOPY);
BYTE *buf=new BYTE[xs*ys*3];
BITMAPINFO bi;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biClrImportant=0;
bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biHeight=ys;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biSizeImage=0;
bi.bmiHeader.biWidth=xs;
GetDIBits(mdc, mbm, 0, ys, buf, &bi, DIB_RGB_COLORS);
HDC dc=GetDC(0);
int xs=GetDeviceCaps(dc,HORZRES);
int ys=GetDeviceCaps(dc,VERTRES);
//obtain offscreen buffer & create copy to operate on it:
HDC mdc=CreateCompatibleDC(dc);
HBITMAP mbm=CreateCompatibleBitmap(dc,xs,ys);
HBITMAP backbm=SelectObject(mdc,mbm);
BitBlt(mdc,0,0,xs,ys,dc,0,0,SRCCOPY);
BYTE *buf=new BYTE[xs*ys*3];
BITMAPINFO bi;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biClrImportant=0;
bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biHeight=ys;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biSizeImage=0;
bi.bmiHeader.biWidth=xs;
GetDIBits(mdc, mbm, 0, ys, buf, &bi, DIB_RGB_COLORS);
Это реальный кусок, он работает.
Я вот на этой неделе (просто для себя) начал писать аналог Radmina, если и ты в эту сторону копаешь, то будет о чем поговорить...
полностью экран "jpeg" получается в ч/б. 60-80 к.б.
в цвете 160-240 к.б. осталость привинтить алгоритм поиска изменений (нарезать фото на фрагменты и проверить)
Код:
#include "jpeg.hpp"
// saved_screen - поток, содержит фото экрана, снятое в прошлый раз
void __fastcall TMyNewRadminServer::Foto()
{
static int cadr=0;
bool new_image=false;
cadr++;
TRect RS=Screen->DesktopRect;
Graphics::TBitmap * c=new Graphics::TBitmap ;
c->Height=RS.Height();
c->Width=RS.Width();
TCanvas* dtCanvas = new TCanvas;
dtCanvas->Handle = GetDC(0);
c->Canvas->CopyRect(RS,dtCanvas,RS);
delete dtCanvas;
if(!DirectoryExists("C:\\MyNewRadminServer\\Test")) ForceDirectories("C:\\MyNewRadminServer\\Test");
String GraphicFileName="C:\\MyNewRadminServer\\Test\\F_"+IntToStr(cadr)+".jpg" ;
TJPEGImage *jpeg;
jpeg = new Jpeg::TJPEGImage();
jpeg->ProgressiveEncoding=true;
jpeg->Grayscale=true;
jpeg->CompressionQuality =70;
jpeg->Smoothing=false;
TMemoryStream *curr=new TMemoryStream;
jpeg->Assign(c);
jpeg->SaveToStream(curr);
if(saved_screen->Size!=curr->Size)
{
new_image=true;
}
if(new_image)
{
curr->Position=0;
curr->SaveToFile(GraphicFileName);
curr->Position=0;
saved_screen->Clear();
curr->SaveToStream(saved_screen);
}
delete jpeg;
delete c;
delete curr;
return;
// saved_screen - поток, содержит фото экрана, снятое в прошлый раз
void __fastcall TMyNewRadminServer::Foto()
{
static int cadr=0;
bool new_image=false;
cadr++;
TRect RS=Screen->DesktopRect;
Graphics::TBitmap * c=new Graphics::TBitmap ;
c->Height=RS.Height();
c->Width=RS.Width();
TCanvas* dtCanvas = new TCanvas;
dtCanvas->Handle = GetDC(0);
c->Canvas->CopyRect(RS,dtCanvas,RS);
delete dtCanvas;
if(!DirectoryExists("C:\\MyNewRadminServer\\Test")) ForceDirectories("C:\\MyNewRadminServer\\Test");
String GraphicFileName="C:\\MyNewRadminServer\\Test\\F_"+IntToStr(cadr)+".jpg" ;
TJPEGImage *jpeg;
jpeg = new Jpeg::TJPEGImage();
jpeg->ProgressiveEncoding=true;
jpeg->Grayscale=true;
jpeg->CompressionQuality =70;
jpeg->Smoothing=false;
TMemoryStream *curr=new TMemoryStream;
jpeg->Assign(c);
jpeg->SaveToStream(curr);
if(saved_screen->Size!=curr->Size)
{
new_image=true;
}
if(new_image)
{
curr->Position=0;
curr->SaveToFile(GraphicFileName);
curr->Position=0;
saved_screen->Clear();
curr->SaveToStream(saved_screen);
}
delete jpeg;
delete c;
delete curr;
return;
Но если будут какие-то вопросы, всегда готов помочь. Тема интересная.
Но сейчас я не пишу, у меня запуск 1С через пару дней, а он глючный получился...
Но это уже другая история...
Все нормально работает, то что и хотел. Всем спасибо. С новым годом :)