Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Полное Копирование BITMAP


Автор: Dmitriy2k 25.8.2009, 12:56
Здравструйте! Помогите решить следущую проблему:
Нужно скопировать BITTMAP c одного компа на другой.
С сетью никаких проблем нет, зато проблема в следующем:
Не получается полностью скопировать HBITMAP хотя бы локальном компьютере.
ведь HBITMAP - лишь unsigned int.
c другой стороны, можно скопировать BITMAP:

Код

typedef struct tagBITMAP
  {
    LONG        bmType;
    LONG        bmWidth;
    LONG        bmHeight;
    LONG        bmWidthBytes;
    WORD        bmPlanes;
    WORD        bmBitsPixel;
    LPVOID      bmBits;
  } BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;



хотя проблема в следущем:
все поля битмапа копируются за исключением LPVOID - явно указатель на массив данных битмапа
Какой он длины - не знаю.  

Начал писать для решения данной проблемы следущую функцию:

Код

int CopyBMP(HBITMAP ishodBMP,HBITMAP conechBMP){
    
    BITMAP bmpIshod,bmpConech;
    
//    Bitmap(
    
    GetObject(ishodBMP,sizeof(BITMAP),&bmpIshod);

    bmpConech=bmpIshod;
    //BYTE *bmpIshodBytes,*bmpConechBytes;

    //bmpIshodBytes=(BYTE*)malloc(bmpIshod.bmWidthBytes);
    //bmpConechBytes=(BYTE*)malloc(bmpIshod.bmWidthBytes);
    
    memcpy(bmpConech.bmBits,bmpIshod.bmBits,bmpIshod.bmWidthBytes);
    
    return 0;
}


Подскажите, как лучше решить данную проблему?

Автор: GremlinProg 25.8.2009, 13:33
если формат битмапа непостоянный: bmp, jpg, png, rle и т.п.,
то за отсутствием соответствующих библиотек по работе с ними
можно просто представить все передаваемые битмапы в неупакованный вид с помощью GetDIBits,

ставь biBitCount в 32, biCompression в BI_RGB и считай число байт:
Код

size = height * width * 4

а уже получившийся "распакованный" битмап копируй куда хочешь

Автор: nworm 25.8.2009, 13:35
Вроде тут что-то есть
http://www.codase.com/search/call?name=CreateBitmapIndirect

Автор: Dmitriy2k 25.8.2009, 19:00
Я не очень уверен, что иду по правильному пути.
Здесь приведен код серверной части моей программы, который отображает скриншот экрана(с масштабированием).
Код


case WM_SIZE:case WM_PAINT:case WM_SETREDRAW:{
         
    PAINTSTRUCT PaintStruct;

    HDC hDC;
    RECT Rect;
    HWND hWnd;
    hWnd=hDlg;
                    //hWnd=GetDlgItem(hDlg,IDC_PICTURE);
    
    
                        //struct BITMAP bmp;
            
    hDC = BeginPaint(hWnd, &PaintStruct);
    HDC hdesktopDC = ::GetDC(0);
    HDC memDC = CreateCompatibleDC(hdesktopDC);
    DWORD dwWidth = GetDeviceCaps(hdesktopDC, HORZRES);
    DWORD dwHeight = GetDeviceCaps(hdesktopDC, VERTRES);
                         //MessageBox(NULL,FString("горизонталь %d,вертикаль %d",dwWidth,dwHeight),"see",MB_OK);
            
    HBITMAP hBMP = CreateCompatibleBitmap(hdesktopDC, dwWidth, dwHeight);
    HBITMAP hConechBMP = CreateCompatibleBitmap(NULL, dwWidth, dwHeight);
    CopyBMP(hBMP,hConechBMP,hdesktopDC);
    HBITMAP oldBitmap = (struct HBITMAP__*)SelectObject(memDC, hBMP);
              //HBITMAP oldBitmap = (struct HBITMAP__*)SelectObject(memDC, hConechBMP);

    BitBlt(memDC, 0, 0, dwWidth, dwHeight, hdesktopDC, 0, 0, SRCCOPY);

    BitBlt(hDC, 0, 0, dwWidth, dwHeight, memDC, 0, 0, SRCCOPY);
          
                         //Определяем размер рабочей области
    GetClientRect(hWnd,&Rect);
            
                         //копируем bitmap c совместимого на основной контекст с масштабированием
    StretchBlt(hDC,0,0,Rect.right,Rect.bottom,memDC,0,0,dwWidth,dwHeight,SRCCOPY);
            //StretchBlt(hDC,0,0,dwWidth,dwHeight,memDC,0,0,dwWidth,dwHeight,SRCCOPY);
                        //вновь делаем старый bitmap текущим
    SelectObject(memDC, oldBitmap);
            
  
    ReleaseDC(hWnd,hdesktopDC);
    DeleteObject(hBMP); 
    EndPaint(hWnd,&PaintStruct);
            
            
    DeleteObject(hConechBMP); 
    }
    break;




GremlinProg

Мне нужно послать клиенту изображение экрана, вот поэтому я и решил послать клиенту BITMAP
Если я правильно мыслю, то нужно по твоему совету воспользоваться функцией GetDIBits

int GetDIBits(
  HDC hdc,           // handle to DC                               // это поле вполне понятно
  HBITMAP hbmp,      // handle to bitmap                   //  это тоже
  UINT uStartScan,   // first scan line to set                ? 
  UINT cScanLines,   // number of scan lines to copy  ?
  LPVOID lpvBits,    // array for bitmap bits                 // мне не очень понятно, каким из этих полей нужно воспользоваться? Этим?
  LPBITMAPINFO lpbi, // bitmap data buffer                // или этим?
  UINT uUsage        // RGB or palette index                ? 
);

и еще: я не нашел в этой функции поле 
  biBitCount и biCompression.
Конечно, я посмотрел эти поля в MSDN, но мне не понятны дальнейшие действия.

Автор: GremlinProg 25.8.2009, 20:56
Dmitriy2k, примеров довольно много, смотри в поиск: http://forum.vingrad.ru/act-Search/CODE/show/searchid-20fea54b3c3bbb9ed5972e3396a2b2f2/search_in-posts/result_type/topics/flag/search/highlite/getdibits/index.html

тебе подойдет любой, который конвертирует битмап в массив байт, этот массив и передавай
а на серверной стороне можно делать обратную операцию, с помощью SetDIBits

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)