这是我的代码,我通过导入一个bmp的文件并显示出来,但是我想让导入的图片变成半透明应该怎么修改
#include "StdAfx.h"
#include "ReadBitmap.h"
#include "../DocData/DocDataBitmap.h"
#include "../ViewAssist/ViewParameter.h"
#include "../DocState/DocInfo.h"
#include "../MainFrm.h"
#include "../SewModel.h"
#include "Wingdi.h"
#include "Windows.h"
static int m_bmp_ext_level = 0; // 位图类的后缀编号
CReadBitmap::CReadBitmap()
{
m_size = false;
m_proc = NULL;
}
CReadBitmap::CReadBitmap(double w, double h)
{
m_size = true;
s_width = w;
s_hight = h;
m_proc = NULL;
}
CReadBitmap::~CReadBitmap()
{
m_proc = NULL;
}
// 读取bmp文件生成图元
bool CReadBitmap::ReadBmpFile(void *doc, CString path, CDocData **des, bool move)
{
bool rlt = false;
// 图层参数
long num = 2;
COLORREF color = RGB(0, 0, 0);
GetLayerNumAndColor(doc, &num, &color);
// 文件读取
BYTE *buf1 = NULL, *buf2 = NULL;
long len1 = 0, len2 = 0;
CFile fp;
if (!fp.Open(path, CFile::modeRead))
return rlt;
len1 = (long)fp.GetLength();
buf1 = new BYTE[len1];
fp.Read(buf1, len1);
fp.Close();
BITMAPFILEHEADER *hdr = (BITMAPFILEHEADER *)buf1;
if (hdr->bfType != 0x4d42)
{
delete[] buf1;
return rlt;
}
BITMAPINFOHEADER *inf = (BITMAPINFOHEADER *)(buf1 + sizeof(BITMAPFILEHEADER));
// 分辨率非法判断
HDC tDC = GetDC(NULL);
if (inf->biXPelsPerMeter <= 0 || inf->biYPelsPerMeter <= 0)
{
if (m_size)
{
inf->biXPelsPerMeter = (long)(inf->biWidth * 1000.0 / s_width + 0.5);
inf->biYPelsPerMeter = (long)(inf->biHeight * 1000.0 / s_hight + 0.5);
}
else
{
inf->biXPelsPerMeter = (long)(1000.0 * GetDeviceCaps(tDC, HORZRES) / GetDeviceCaps(tDC, HORZSIZE) + 0.5);
inf->biYPelsPerMeter = (long)(1000.0 * GetDeviceCaps(tDC, VERTRES) / GetDeviceCaps(tDC, VERTSIZE) + 0.5);
}
}
DeleteObject(tDC);
// 位及长宽非法判断
long ht = inf->biHeight;
long wd = inf->biWidth + (4 - inf->biWidth % 4) % 4;
len2 = 54 + sizeof(RGBQUAD) * 256 + ht * wd;
if (len2 > len1 && inf->biBitCount >= 8)
{
delete[] buf1;
return rlt;
}
buf2 = new BYTE[len2];
// 灰度转换
BYTE bmp_type = 1;
DibToGray(buf1, buf2);
// 临时文件
// CString work = CViewParam::GetSftWorkPath();
CString work = L"C:\\Users\\top20240426\\Desktop\\keygen_new(2032)\\sew";
work.Replace(TEXT("\\\\"), TEXT("\\"));
work.Replace(TEXT("\\work\\"), TEXT("\\file\\"));
CString tmp = work;
long ps = path.ReverseFind('\\');
CString ext;
ext.Format(TEXT("%d%d"), bmp_type, m_bmp_ext_level);
m_bmp_ext_level++;
ext += path.Right(path.GetLength() - ps - 1);
tmp += ext;
if (fp.Open(tmp, CFile::modeCreate | CFile::modeWrite))
{
fp.Write(buf2, len2);
fp.Close();
// 图层图元
CDocInfo *dci = (CDocInfo *)doc;
double px = move ? dci->m_mouse_pos.x : (LOGIC_MAX_X / 2);
double py = move ? dci->m_mouse_pos.y : (LOGIC_MAX_Y / 2);
CDocData *met = new CDocDataBitmap(dci, path, tmp, px, py, bmp_type);
met->m_color = color;
met->m_num = num;
*des = met;
rlt = true;
}
delete[] buf1;
delete[] buf2;
buf1 = NULL;
buf2 = NULL;
return rlt;
}
// 转24/8/1位位图为8位灰度图并保存到指定路径
bool CReadBitmap::DibToGray(BYTE *buf1, BYTE *buf2)
{
bool rlt = false;
long i, j;
BITMAPFILEHEADER *hdr1 = (BITMAPFILEHEADER *)buf1;
BITMAPINFOHEADER *inf1 = (BITMAPINFOHEADER *)(hdr1 + 1);
BITMAPFILEHEADER *hdr2 = (BITMAPFILEHEADER *)buf2;
BITMAPINFOHEADER *inf2 = (BITMAPINFOHEADER *)(hdr2 + 1);
*hdr2 = *hdr1;
*inf2 = *inf1;
// 修改头
inf2->biBitCount = 8;
inf2->biClrUsed = 256;
inf2->biSizeImage = (inf2->biWidth + (4 - inf2->biWidth % 4) % 4) * inf2->biHeight;
inf2->biXPelsPerMeter = inf1->biXPelsPerMeter;
inf2->biYPelsPerMeter = inf1->biYPelsPerMeter;
hdr2->bfOffBits = 54 + inf2->biClrUsed * sizeof(RGBQUAD);
hdr2->bfSize = hdr2->bfOffBits + inf2->biSizeImage;
// 位图数据
BYTE back[4];
memset(back, 255, 4);
BYTE rsv1;
BYTE rsv2 = (4 - inf2->biWidth % 4) % 4;
BYTE *bit1 = buf1 + hdr1->bfOffBits;
BYTE *bit2 = buf2 + hdr2->bfOffBits;
if (inf1->biBitCount == 24 || inf1->biBitCount == 32)
{
if (inf1->biBitCount == 24)
rsv1 = (4 - (inf1->biWidth * 3) % 4) % 4;
else
rsv1 = 0;
// 颜色表
RGBQUAD *rgbquad = (RGBQUAD *)(buf2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
for (i = 0; i < 256; i++)
{
rgbquad[i].rgbBlue = rgbquad[i].rgbGreen = rgbquad[i].rgbRed = (BYTE)i;
rgbquad[i].rgbReserved = 0;
}
// 位数据
long itm = 0;
for (i = 0; i < inf2->biHeight; i++)
{
for (j = 0; j < inf2->biWidth; j++)
{
bit2[i * (inf2->biWidth + rsv2) + j] = (BYTE)((306 * bit1[itm] + 601 * bit1[itm + 1] + 117 * bit1[itm + 2]) >> 10);
if (inf1->biBitCount == 24)
itm += 3;
else
{
itm += 4;
bit2[i * (inf2->biWidth + rsv2) + 3] = 128;
}
}
itm += rsv1;
memcpy(bit2 + i * (inf2->biWidth + rsv2) + j, back, rsv2); // 填写冗余空间
}
rlt = true;
}
else if (inf1->biBitCount == 8)
{
rsv1 = rsv2;
BYTE gray;
RGBQUAD *rgbquad = (RGBQUAD *)(buf2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
RGBQUAD *rgb = (RGBQUAD *)(buf1 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
for (i = 0; i < 256; i++)
{
gray = (BYTE)((306 * rgb[i].rgbRed + 601 * rgb[i].rgbGreen + 117 * rgb[i].rgbBlue) >> 10);
rgbquad[i].rgbBlue = rgbquad[i].rgbGreen = rgbquad[i].rgbRed = gray;
rgbquad[i].rgbReserved = 0;
}
// 写位图
for (i = 0; i < inf2->biHeight; i++)
{
for (j = 0; j < inf2->biWidth; j++)
{
bit2[i * (inf2->biWidth + rsv2) + j] = bit1[i * (inf1->biWidth + rsv1) + j];
}
memcpy(bit2 + i * (inf2->biWidth + rsv2) + j, back, rsv2); // 填写冗余空间
}
rlt = true;
}
else if (inf1->biBitCount == 1)
{
long b1row = (inf1->biWidth % 8) ? (inf1->biWidth / 8 + 1) : (inf1->biWidth / 8);
rsv1 = (4 - b1row % 4) % 4;
RGBQUAD *rgbquad = (RGBQUAD *)(buf2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
for (i = 0; i < 256; i++)
{
rgbquad[i].rgbBlue = rgbquad[i].rgbGreen = rgbquad[i].rgbRed = (BYTE)i;
rgbquad[i].rgbReserved = 0;
}
// 写位图
RGBQUAD *rgb = (RGBQUAD *)(buf1 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
BYTE valu0, valu1, *lpIn, *lpOut;
if (rgb->rgbBlue > 0)
{
valu0 = 255;
valu1 = 0;
}
else
{
valu0 = 0;
valu1 = 255;
}
long k;
for (i = 0; i < inf2->biHeight; i++)
{
k = 8;
lpIn = bit1 + i * (b1row + rsv1);
lpOut = bit2 + i * (inf2->biWidth + rsv2);
for (j = 0; j < inf2->biWidth; j++)
{
k--;
if (Mac_BitIf(*lpIn, k))
*lpOut = valu1;
else
*lpOut = valu0;
lpOut++;
if (k <= 0)
{
lpIn++;
k = 8;
}
}
for (j = 0; j < rsv2; j++)
*lpOut++ = valu0; // 填写冗余空间
}
rlt = true;
}
return rlt;
}
// 灰度反色
bool CReadBitmap::GrayReverse(CString path)
{
CFile fp;
// 读取
if (!fp.Open(path, CFile::modeRead))
return false;
long length = (long)fp.GetLength();
BYTE *buf = new BYTE[length];
fp.Read(buf, length);
fp.Close();
// 反转
long pos;
BITMAPFILEHEADER *hdr = (BITMAPFILEHEADER *)buf;
BITMAPINFOHEADER *inf = (BITMAPINFOHEADER *)(hdr + 1);
long wd = inf->biWidth + (4 - inf->biWidth % 4) % 4;
BYTE *bit = buf + hdr->bfOffBits;
for (int i = 0; i < inf->biHeight; i++)
{
for (int j = 0; j < inf->biWidth; j++)
{
pos = wd * i + j;
bit[pos] = 255 - bit[pos];
}
}
// 写入
if (!fp.Open(path, CFile::modeWrite))
{
delete[] buf;
return false;
}
fp.Write(buf, length);
fp.Close();
delete[] buf;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////
// 获取空闲的图层序号和颜色
void CReadBitmap::GetLayerNumAndColor(void *doc, long *num, COLORREF *color)
{
CDocInfo *dci = (CDocInfo *)doc;
if (!dci)
{
*num = 0;
return;
}
// 遍历空闲
bool fre;
CDocData *met = NULL;
for (int i = COLOR_SUM - 1; i >= 0; i--)
{
fre = true;
// 图元
met = ((CDocListNode *)dci->m_file_data)->m_meta;
while (met)
{
if (met->m_num == i)
{
fre = false;
break;
}
met = met->next;
}
if (fre)
{
*num = i % COLOR_SUM;
*color = m_sys_param.m_color[*num];
break;
}
}
// 未找到则生成一个序号
long max_num = -1;
if (!fre)
{
// 图元
met = ((CDocListNode *)dci->m_file_data)->m_meta;
while (met)
{
max_num = max(max_num, met->m_num);
met = met->next;
}
max_num++;
*num = max_num;
*color = RGB(0, 0, 0);
}
}
//////////////////////////////////////////////////////////////////
// 转换jpg格式为bmp格式并保存到指定路径文件名
bool CReadBitmap::JpegPngGifToBmp(CString src, CString des)
{
Image image(src); // 装入图像文件
CLSID clsid;
if (GetImageCLSID(L"image/bmp", &clsid))
{
image.Save(des, &clsid, NULL);
}
return true;
}
int CReadBitmap::GetImageCLSID(CString format, CLSID *pCLSID)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo *pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return FALSE; // 编码信息不可用
// 分配内存
pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
if (pImageCodecInfo == NULL)
return FALSE; // 分配失败
// 获得系统中可用的编码方式的所有信息
GetImageEncoders(num, size, pImageCodecInfo);
// 在可用编码信息中查找format格式是否被支持
for (UINT i = 0; i < num; ++i)
{
// MimeType:编码方式的具体描述
if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0)
{
*pCLSID = pImageCodecInfo[i].Clsid;
free(pImageCodecInfo);
return TRUE;
}
}
free(pImageCodecInfo);
return FALSE;
}