weixin_46027762 2024-09-04 10:18 采纳率: 65.7%
浏览 15
已结题

mcf中怎么实现导入的图片变成透明

这是我的代码,我通过导入一个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;
}

  • 写回答

23条回答 默认 最新

  • churuxu 2024-09-04 10:38
    关注

    私聊,帮你搞定

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(22条)

报告相同问题?

问题事件

  • 系统已结题 9月13日
  • 已采纳回答 9月5日
  • 创建了问题 9月4日

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀