Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите с BitMap

9.3K
23 декабря 2004 года
lai
4 / / 23.12.2004
Как получить указатель на 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);
Но чего-то не получается. Скажите, почему указатель на массив bm.bmBits=NULL

Что я делал не так???
И как надо сделать правильно???
7.3K
24 декабря 2004 года
Necro666
17 / / 20.07.2004
Код:
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);
246
24 декабря 2004 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by lai
Как получить указатель на 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);
Но чего-то не получается. Скажите, почему указатель на массив bm.bmBits=NULL

Что я делал не так???
И как надо сделать правильно???


Код:
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;
}
9.3K
24 декабря 2004 года
lai
4 / / 23.12.2004
GIZMO, по твоему варианту TBitmap будет обрабатывать все сам. Мне бы не хотелось использовать класс ТBitmap, а сделать все это на уровне Api.
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;
}

7.3K
27 декабря 2004 года
Necro666
17 / / 20.07.2004
Я, видимо, неудачно выразился. В общем, у тебя в битмэпе данных нет, потому что их там нет. Нужно создать совместимый контекст в памяти (CreateCompatibleDC()), выбрать в него картинку (SelectObject(), не забудь сохранить значение, возвращаемое функцией!), скопировать (BitBlt(ScreenDC->MemoryDC)), и только после этого брать данные. Привожу кусок побольше:
Код:
//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);

Это реальный кусок, он работает.
2.3K
27 декабря 2004 года
ART-CODE
134 / / 15.11.2004
Если не секркт. что пишешь ?
Я вот на этой неделе (просто для себя) начал писать аналог 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;
7.3K
28 декабря 2004 года
Necro666
17 / / 20.07.2004
Нет, я фигню писал. На, зацени.
Но если будут какие-то вопросы, всегда готов помочь. Тема интересная.

Но сейчас я не пишу, у меня запуск 1С через пару дней, а он глючный получился...
Но это уже другая история...
9.3K
31 декабря 2004 года
lai
4 / / 23.12.2004
Все нормально работает, то что и хотел. Всем спасибо. С новым годом :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог