#include "stdafx.h" #include "bmp_control.h" //#include #include #include #define ALINEAMIENTO_DWORDEX(x) ((x+4)&~4) #define ALINEAMIENTO_DWORD(x) ((x+3)&~3) #define WIDTHBYTES(i) ((i+31)/32*4) //************************************************************************************** Cbmp_control::Cbmp_control(int cx, int cy) { ancho=cx; alto=cy; bmp_info=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)]; bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmp_info->bmiHeader.biWidth=cx; bmp_info->bmiHeader.biHeight=cy; bmp_info->bmiHeader.biPlanes=1; bmp_info->bmiHeader.biBitCount=16; bmp_info->bmiHeader.biCompression=0; bmp_info->bmiHeader.biSizeImage=0; bmp_info->bmiHeader.biXPelsPerMeter=0; bmp_info->bmiHeader.biYPelsPerMeter=0; bmp_info->bmiHeader.biClrUsed=0; bmp_info->bmiHeader.biClrImportant=0; bmp_info->bmiHeader.biCompression=BI_RGB; bmp_info->bmiHeader.biBitCount=32; bits=NULL; m_cdc=NULL; crea(); } //************************************************************************************** Cbmp_control::~Cbmp_control() { destruye(); delete bmp_info; } //************************************************************************************** void Cbmp_control::destruye() { if (bits!=NULL) { ::SelectObject(m_hdc, m_old_bitmap); ::DeleteObject(m_bitmap); ::DeleteDC(m_hdc); delete m_cdc; m_cdc=NULL; bits=NULL; }; } //************************************************************************************** void Cbmp_control::crea(BOOL limpiar, char ch) { destruye(); HDC sdc=::GetDC(NULL); m_hdc=::CreateCompatibleDC(sdc); ::ReleaseDC(0,sdc); LPVOID lp; bmp_info->bmiHeader.biSizeImage = ((256 * (bmp_info->bmiHeader.biBitCount / 8) + 3) & -4) * 192; m_bitmap=::CreateDIBSection(m_hdc,bmp_info,DIB_PAL_COLORS,&lp,NULL,NULL); DWORD dw = GetLastError(); bits=(BYTE*)lp; if (bits==NULL) { //ASSERT(FALSE); //AfxMessageBox(TEXT("sin memoria!")); ::DeleteDC(m_hdc); m_hdc = NULL; return; } m_old_bitmap=(HBITMAP)::SelectObject(m_hdc, m_bitmap); m_cdc=new CDC(); m_cdc->Attach(m_hdc); if (limpiar) rellena_bits(ch); m_iniciado=FALSE; } //************************************************************************************** /* int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; Gdiplus::GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure Gdiplus::GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure } BOOL Cbmp_control::guardar_bmp(char *path) { Gdiplus::Bitmap *gr=Gdiplus::Bitmap::FromHBITMAP(m_bitmap,NULL); // Save the altered image. CLSID pngClsid; GetEncoderClsid(L"image/bmp", &pngClsid); gr->Save(L"c:\\temp\\ola.bmp",&pngClsid,NULL); return TRUE; };*/ //************************************************************************************** void Cbmp_control::redimensiona(int cx, int cy, BOOL limpiar, char ch) { if (cx!=ancho || cy!=alto) { ancho=cx; alto=cy; bmp_info->bmiHeader.biWidth=cx; bmp_info->bmiHeader.biHeight=cy; crea(limpiar, ch); } else { if (limpiar) rellena_bits(ch); }; } //************************************************************************************** void Cbmp_control::rellena_bits(char ch) { int aaa=WIDTHBYTES(ancho*24); int fdf=ALINEAMIENTO_DWORD(ancho*4); if (bits!=NULL) memset(bits, ch, alto*fdf); } //************************************************************************************** void Cbmp_control::pon_bits(LPVOID src, int count) { /*ASSERT(count<=alto*ALINEAMIENTO_DWORD(ancho)); LPVOID lp=(LPVOID)bits; count>>=2; _asm { push ds; pop es; mov edi, dword ptr [lp]; mov esi, dword ptr [src]; cld; mov ecx, count; rep movsd; }; /* if (count>Height*DWordAlign(Width)) return; memcpy((LPVOID)Dib, src, count); */ } //************************************************************************************** HDC Cbmp_control::dame_hdc() { if (bits!=NULL) return m_hdc; else return 0; return 0; } //************************************************************************************** CDC* Cbmp_control::dame_cdc() { if (bits!=NULL) return m_cdc; else return NULL; return NULL; } //************************************************************************************** void Cbmp_control::pinta_dib( HDC dc, CRect r ) { if (bits!=NULL) { SetDIBitsToDevice(dc,r.left,r.top,r.Width(), r.Height(),r.left,bmp_info->bmiHeader.biHeight-r.bottom ,0 ,bmp_info->bmiHeader.biHeight , bits, bmp_info,DIB_RGB_COLORS); } } //************************************************************************************** void Cbmp_control::escribe_pixel(int x, int y, BYTE valor) { if (bits==NULL) return; if (x<0 || y<0 || x>=ancho || y>=alto) return; //m_bits[(m_alto-y-1)*WIDTHBYTES((m_ancho)+x)]=valor; //m_bits[(m_alto-y-1)*WIDTHBYTES(ALINEAMIENTO_DWORD(m_ancho))+200]=valor;//WIDTHBYTES(4*((m_ancho)+(x)))]=valor; //m_bits[367+ALINEAMIENTO_DWORD(x)]=valor;//WIDTHBYTES(4*((m_ancho)+(x)))]=valor; int ff=ALINEAMIENTO_DWORD(ancho*4); int fff=WIDTHBYTES(ancho)*8; bits[(alto-y-1)*(ff)+x*4+0]=valor; bits[(alto-y-1)*(ff)+x*4+1]=valor; bits[(alto-y-1)*(ff)+x*4+2]=valor; bits[(alto-y-1)*(ff)+x*4+3]=255; //m_bits[sizeof(BITMAPINFOHEADER)+(m_alto-y-1)*(fff)+120]=valor; //m_bits[(m_alto-y-1)*(ALINEAMIENTO_DWORD(m_ancho))+200]=valor;// //m_bits[(m_alto-y-1)*(ALINEAMIENTO_DWORD(m_ancho))+200]=valor;// //m_bits[ (y * m_ancho * 4) + (x * 4) + 0 ]=valor; } //************************************************************************************** void Cbmp_control::colorea_pixel(int x, int y, BYTE valor) { int res=WIDTHBYTES(ancho*24); if (bits==NULL) return; if (x<0 || y<0 || x>=ancho || y>=alto) return; //int index=(m_alto-y-1)*ALINEAMIENTO_DWORD(m_ancho)+x; //int index=(m_alto-y-1)*(m_ancho)+x; bits[(alto-y-1) + 20]=valor; bits[(alto-y-1) + 21]=valor; //m_bits[(m_alto-y-1)*(ALINEAMIENTO_DWORD(m_ancho))+x+1]=valor+25; //m_bits[(m_alto-y-1)*(ALINEAMIENTO_DWORD(m_ancho))+x+2]=valor+180; } //************************************************************************************** void Cbmp_control::pinta_cruz(int x, int y, int ancho, BYTE color) { if (bits==NULL) return; int i; for (i=y-ancho; i<=y+ancho; i++) escribe_pixel(x, i, color); for (i=x-ancho; i<=x+ancho; i++) escribe_pixel(i, y, color); } //************************************************************************************** void Cbmp_control::mueve_datos(int cx, int cy) { if (bits==NULL) return; LPVOID lp1, lp2; if (cx!=0) { // mueve datos en x if (abs(cx)GetClientRect(&r); rec=&r; } redimensiona(rec->Width(),rec->Height()); if(!::BitBlt(m_hdc, 0, 0, ancho, alto, w->GetDC()->m_hDC, rec->left, rec->top, SRCCOPY)) return FALSE; return TRUE; } //************************************************************************************** BOOL Cbmp_control::dib2file( char *path ) { if (bits==NULL) { return FALSE; } BOOL result = FALSE; PICTDESC pd; pd.cbSizeofstruct = sizeof(PICTDESC); pd.picType = PICTYPE_BITMAP; pd.bmp.hbitmap = m_bitmap; pd.bmp.hpal = 0; LPPICTURE picture; HRESULT res = OleCreatePictureIndirect(&pd, IID_IPicture, false, reinterpret_cast(&picture)); if (!SUCCEEDED(res)) return FALSE; LPSTREAM stream; res = CreateStreamOnHGlobal(0, true, &stream); if (!SUCCEEDED(res)) { picture->Release(); return FALSE; } LONG bytes_streamed; res = picture->SaveAsFile(stream, true, &bytes_streamed); HANDLE file = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (!SUCCEEDED(res) || !file) { stream->Release(); picture->Release(); return FALSE; } HGLOBAL mem = 0; GetHGlobalFromStream(stream, &mem); LPVOID data = GlobalLock(mem); DWORD bytes_written; result = !!WriteFile(file, data, bytes_streamed, &bytes_written, 0); result &= (bytes_written == static_cast(bytes_streamed)); GlobalUnlock(mem); CloseHandle(file); stream->Release(); picture->Release(); return result; // Free memory. /*BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = ancho; bi.bmiHeader.biHeight = alto; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24;*/ /*BITMAPFILEHEADER bh; ZeroMemory(&bh, sizeof(BITMAPFILEHEADER)); bh.bfType = 0x4d42; //bitmap bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bh.bfSize = bh.bfOffBits + ((alto*ancho)*3); CFile file; if(!file.Open(path, CFile::modeCreate | CFile::modeWrite)) { return FALSE; } file.Write(&bh, sizeof(BITMAPFILEHEADER)); file.Write(&(bmp_info->bmiHeader), sizeof(BITMAPINFOHEADER)); file.Write(bits, 3 * alto*ancho); file.Close();*/ //return TRUE; } //************************************************************************************** BOOL Cbmp_control::w2file(CWnd *w,char* path, CRect *rec) { CRect r; if (!rec) { w->GetClientRect(&r); rec=&r; } Cbmp_control cnt(rec->Width(),rec->Height()); cnt.pon_iniciado(TRUE); return cnt.w2dib(w,rec) && cnt.dib2file(path); } //**************************************************************************************