utiles_v2017/bmp_control.cpp

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);
}
//**************************************************************************************