429 lines
11 KiB
C++
429 lines
11 KiB
C++
|
|
#include "stdafx.h"
|
|
#include "bmp_control.h"
|
|
//#include <gdiplus.h>
|
|
#include <gdiplus.h>
|
|
#include <mbstring.h>
|
|
|
|
#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)<ancho)
|
|
{
|
|
for (int i=0; i<alto; i++)
|
|
{
|
|
lp1=(LPVOID)((BYTE*)bits+i*ALINEAMIENTO_DWORD(ancho));
|
|
lp2=(LPVOID)((BYTE*)bits+i*ALINEAMIENTO_DWORD(ancho)+abs(cx));
|
|
if (cx<0)
|
|
memcpy(lp2, lp1, ancho-abs(cx));
|
|
else
|
|
memcpy(lp1, lp2, ancho-abs(cx));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cy!=0)
|
|
{ // mueve datos en y
|
|
if (abs(cy)<alto)
|
|
{
|
|
if (cy<0)
|
|
{ // mueve datos hacia abajo
|
|
for (int i=0; i<alto-abs(cy); i++)
|
|
{
|
|
lp2=(LPVOID)((BYTE*)bits+i*ALINEAMIENTO_DWORD(ancho));
|
|
lp1=(LPVOID)((BYTE*)bits+(i+abs(cy))*ALINEAMIENTO_DWORD(ancho));
|
|
memcpy(lp2, lp1, ancho);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
for (int i=0; i<alto-abs(cy); i++)
|
|
{
|
|
lp2=(LPVOID)((BYTE*)bits+(alto-i-1)*ALINEAMIENTO_DWORD(ancho));
|
|
lp1=(LPVOID)((BYTE*)bits+(alto-i-abs(cy)-1)*ALINEAMIENTO_DWORD(ancho));
|
|
memcpy(lp2, lp1, ancho);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//**************************************************************************************
|
|
BOOL Cbmp_control::w2dib( CWnd *w, CRect *rec, DWORD flags)
|
|
{
|
|
CRect r;
|
|
if (bits==NULL)
|
|
return FALSE;
|
|
if(!rec)
|
|
{
|
|
w->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<void**>(&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<DWORD>(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);
|
|
|
|
}
|
|
//**************************************************************************************
|