BMP合成字幕功能

szesin 2008-02-21 03:30:17
在http://topic.csdn.net/t/20050406/08/3912354.html#有过这个问题的提问
正好小弟现在也涉及到了同样的问题
希望大侠给予指导和帮助,谢谢

过程和要求:
处理BMP图片,把文字信息直接写入图片,不需要读出来。
应用程序中调用一个自己写的这个动态库,传入BMP图片数据的地址, 把字符叠加后的BMP图像数据传出来
...全文
393 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljhmt 2012-03-20
  • 打赏
  • 举报
回复
各位高手在LINUX下怎么做这个事啊!!把字符写入位图!
yongziqd 2010-12-28
  • 打赏
  • 举报
回复
楼主,你的问题怎么解决的啊?
我调用了程序,背景是灰色的,但是文字显示了.
YFY 2008-02-27
  • 打赏
  • 举报
回复
怪不得没收到邮件,呵呵。
szesin 2008-02-26
  • 打赏
  • 举报
回复
老大,可以了
是我没有把它的长度和宽度设成一致

导致输出不正确

sorry


现在正在进行中,之后如再有其它问题,再请教
YFY 2008-02-25
  • 打赏
  • 举报
回复
我们公司禁止上聊天工具的。

下班后有时间我可以帮你看看。
szesin 2008-02-25
  • 打赏
  • 举报
回复
ConvertYUVtoRGB()没有声明

其实其写入保存工作
我在我的代码里已经做了啊
( CFile savafile;
bOpen = savafile.Open("D:\\dx.bmp", CFile::modeCreate|CFile::modeWrite);
if (!bOpen)
{
AfxMessageBox("保存位图失败");
return S_FALSE ;
}

savafile.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
savafile.Write((LPVOID) m_lpBMPHdr, size);
savafile.Write((LPVOID)(lpImageDest), m_dwImageSize);
savafile.Close();


即使是调用了你的PSAWriteBMPFile()函数(但未做YUVTORGB转换),也不能得到想要的结果,因为这个项目有点急,如果您有时间,能否帮忙帮到底,加一下小弟的QQ:6038515
YFY 2008-02-25
  • 打赏
  • 举报
回复
你可以把源码打包发到tianyi21cn@126.com,明天晚上我回家可以给你看看。

我做了动态库的,引用动态库即可调用。

其中IDC_STATIC_PIC是一个VC6上的图片控件。
szesin 2008-02-25
  • 打赏
  • 举报
回复
天易兄,你的两个函数(即PSAFreeCharToImageInit()、PSAFreeCharToImage())可以正常调用的么?
我这里不但叠加不成,而且还是全黑的

不知怎么可以把我的代码发你,你帮我看一看
YFY 2008-02-25
  • 打赏
  • 举报
回复
字符叠加实现完全正常,测试样例如下:

void CMutiThreadDlg::OnBtnAddchar()
{
int iRet = -999;
int rgbWidth = 360;
int rgbHeight = 288;
BYTE* lpRGBImageBuffer;
BYTE* lpRGBImageBufferAddChar;
DWORD dwRGBImageSize = 0;

dwRGBImageSize = rgbWidth * rgbHeight * 3;
lpRGBImageBufferAddChar = new BYTE[dwRGBImageSize];
lpRGBImageBuffer = new BYTE[dwRGBImageSize];

DWORD hDc = 0;
hDc = (DWORD)::GetDC(GetDlgItem(IDC_STATIC_PIC)->GetSafeHwnd());

iRet = PSAFreeCharToImageInit(
hDc,
rgbWidth,
rgbHeight,
"宋体",
16,
1,
0,
0,
0,
0,
255,
255);

iRet = PSAFreeCharToImage(lpRGBImageBuffer,
lpRGBImageBufferAddChar,
"叠加字符串1",
"叠加字符串2",
"叠加字符串3",
3,
3,
3,
25,
3,
263);


PSAWriteBMPFile("D:\\x.bmp",360,288,lpRGBImageBufferAddChar);

PSAFreeCharToImageEnd();

if (lpRGBImageBuffer != NULL) // 释放内存:无字符叠加RGB数据
{
delete[] lpRGBImageBuffer;
lpRGBImageBuffer = NULL;
}

if (lpRGBImageBufferAddChar != NULL) // 释放内存:有字符叠加RGB数据
{
delete[] lpRGBImageBufferAddChar;
lpRGBImageBufferAddChar = NULL;
}
}

其中PSAWriteBMPFile改写一点:
int PSAWriteBMPFile(
LPCSTR lpszBMPFile,
int imageWidth,
int imageHeight,
BYTE *lpRGBImageBuffer
)
{
int res = 0;
FILE* fileWrite;

BITMAPFILEHEADER bmFileHeader;
BITMAPINFO bmInfo;
DWORD dwRGBImageSize = imageWidth * imageHeight * 3;
BYTE lpFileHeader[128];
int ibmFileHeaderSize;

bmFileHeader.bfType = 0x4D42;
bmFileHeader.bfSize = 54 + dwRGBImageSize;
bmFileHeader.bfOffBits = 54;
bmFileHeader.bfReserved1 = 0;
bmFileHeader.bfReserved2 = 0;

bmInfo.bmiHeader.biBitCount = 24;
bmInfo.bmiHeader.biClrImportant = 0;
bmInfo.bmiHeader.biClrUsed = 0;
bmInfo.bmiHeader.biCompression = 0;
bmInfo.bmiHeader.biHeight = imageHeight;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biSize = 40;
bmInfo.bmiHeader.biSizeImage = dwRGBImageSize;
bmInfo.bmiHeader.biWidth = imageWidth;
bmInfo.bmiHeader.biXPelsPerMeter = 0;
bmInfo.bmiHeader.biYPelsPerMeter = 0;

fileWrite = fopen(lpszBMPFile,"wb");
if (fileWrite == NULL)
{
res = 1;
goto Exit;
}

ibmFileHeaderSize = sizeof(BITMAPFILEHEADER);
memcpy(lpFileHeader,&bmFileHeader,ibmFileHeaderSize);
memcpy(&lpFileHeader[ibmFileHeaderSize],&bmInfo.bmiHeader,sizeof(BITMAPINFOHEADER));

if (fwrite(lpFileHeader,sizeof(BYTE),54,fileWrite) != 54)
{
fclose(fileWrite);
res = 5;
goto Exit;
}

if (fwrite(lpRGBImageBuffer, sizeof(BYTE), dwRGBImageSize, fileWrite) != dwRGBImageSize)
{
fclose(fileWrite);
res = 4;
goto Exit;
}

Exit:
if (res != 1)
{
fclose(fileWrite);
}

return res;
}

兄弟,你这回复搞得阿好累,呵呵。
cangwu_lee 2008-02-22
  • 打赏
  • 举报
回复

寫得真詳細了
szesin 2008-02-22
  • 打赏
  • 举报
回复
好的
谢谢

我试一下先
YFY 2008-02-22
  • 打赏
  • 举报
回复
先在黑图中生成字符试试。

/************************************************************************
extern "C" EXPORTS Function PSAWriteBMPFile:
保存为BMP格式的图像
Input:
LPCSTR lpszBMPFile 需要保存的文件名称(全路径完整名称)
int imageWidth 图像宽度
int imageHeight 图像高度
BYTE *lpRawImageBuffer 图像缓存
return::
正常返回0值,非0值表示失败;
Update:
Author Date Ver Remark
Shimingjie 2005/08/31 1.0 Create
************************************************************************/
extern "C" int PASCAL EXPORT PSAWriteBMPFile(
LPCSTR lpszBMPFile,
int imageWidth,
int imageHeight,
BYTE *lpRawImageBuffer
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

int res = 0;
FILE* fileWrite;

BYTE* lpRGBImageBuffer;
BITMAPFILEHEADER bmFileHeader;
BITMAPINFO bmInfo;
DWORD dwRGBImageSize = imageWidth * imageHeight * 3;
BYTE lpFileHeader[128];
int ibmFileHeaderSize;

bmFileHeader.bfType = 0x4D42;
bmFileHeader.bfSize = 54 + dwRGBImageSize;
bmFileHeader.bfOffBits = 54;
bmFileHeader.bfReserved1 = 0;
bmFileHeader.bfReserved2 = 0;

bmInfo.bmiHeader.biBitCount = 24;
bmInfo.bmiHeader.biClrImportant = 0;
bmInfo.bmiHeader.biClrUsed = 0;
bmInfo.bmiHeader.biCompression = 0;
bmInfo.bmiHeader.biHeight = imageHeight;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biSize = 40;
bmInfo.bmiHeader.biSizeImage = dwRGBImageSize;
bmInfo.bmiHeader.biWidth = imageWidth;
bmInfo.bmiHeader.biXPelsPerMeter = 0;
bmInfo.bmiHeader.biYPelsPerMeter = 0;

lpRGBImageBuffer = new BYTE[dwRGBImageSize];

ConvertYUVtoRGB(lpRawImageBuffer,lpRGBImageBuffer,imageWidth,imageHeight);

fileWrite = fopen(lpszBMPFile,"wb");
if (fileWrite == NULL)
{
res = 1;
goto Exit;
}

ibmFileHeaderSize = sizeof(BITMAPFILEHEADER);
memcpy(lpFileHeader,&bmFileHeader,ibmFileHeaderSize);
memcpy(&lpFileHeader[ibmFileHeaderSize],&bmInfo.bmiHeader,sizeof(BITMAPINFOHEADER));

if (fwrite(lpFileHeader,sizeof(BYTE),54,fileWrite) != 54)
{
fclose(fileWrite);
res = 5;
goto Exit;
}

/*
if (fwrite(&bmFileHeader,sizeof(BITMAPFILEHEADER),1,fileWrite) != sizeof(BITMAPFILEHEADER))
{
fclose(fileWrite);
res = 2;
goto Exit;
}

if (fwrite(&bmInfo.bmiHeader,sizeof(BITMAPINFOHEADER ),1,fileWrite) != sizeof(BITMAPINFOHEADER ))
{
fclose(fileWrite);
res = 3;
goto Exit;
}
*/

if (fwrite(lpRGBImageBuffer, sizeof(BYTE), dwRGBImageSize, fileWrite) != dwRGBImageSize)
{
fclose(fileWrite);
res = 4;
goto Exit;
}

Exit:
if (res != 1)
{
fclose(fileWrite);
}
if (lpRGBImageBuffer != NULL)
{
delete[] lpRGBImageBuffer;
lpRGBImageBuffer = NULL;
}

return res;
}
szesin 2008-02-22
  • 打赏
  • 举报
回复
/* ChangeFunction(LPSTR strPath) */
m_DealWith.PSAFreeCharToImageInit(0,20,20,"ss",14,0,0,0,0,220,220,220);

LPBYTE lpImageSrc = NULL ;
LPBYTE lpImageDest = NULL ;

CFile file;
int size = 0;
UINT uCounts = 0;
LPBITMAPINFOHEADER m_lpBMPHdr = NULL; //BITMAPINFOHEADER信息

BOOL bOpen = file.Open(strPath, CFile::modeRead);
if (!bOpen)
{
AfxMessageBox("读取位图文件出错");
return S_FALSE ;
}

BITMAPFILEHEADER bmfh;
ZeroMemory(&bmfh, sizeof(BITMAPFILEHEADER));
uCounts = file.Read((LPVOID) &bmfh,
sizeof(BITMAPFILEHEADER));
if(uCounts != sizeof(BITMAPFILEHEADER))
{
AfxMessageBox("读取位图文件出错");
return S_FALSE ;
}
if(bmfh.bfType != 0x4d42)
{
AfxMessageBox("本文件不是位图图片");
return S_FALSE ;
}
size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
if (m_lpBMPHdr != NULL)
{
delete[] m_lpBMPHdr;
m_lpBMPHdr = NULL;
}
m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size];
// BITMAPINFOHEADER和颜色表
uCounts = file.Read(m_lpBMPHdr, size);

if (lpImageSrc != NULL)
{
delete[] lpImageSrc;
lpImageSrc = NULL;
}

DWORD m_dwImageSize = m_lpBMPHdr->biSizeImage;
lpImageSrc = (LPBYTE) new char[m_dwImageSize];

uCounts = file.Read(lpImageSrc, m_dwImageSize);
file.Close();

lpImageDest = new BYTE[m_dwImageSize];
ZeroMemory(lpImageDest, m_dwImageSize);
//deal with
m_DealWith.PSAFreeCharToImage(lpImageSrc,lpImageDest,"aaaaa","\0","\0",80,80,0,0,0,0);

CFile savafile;
bOpen = savafile.Open("D:\\dx.bmp", CFile::modeCreate|CFile::modeWrite);
if (!bOpen)
{
AfxMessageBox("保存位图失败");
return S_FALSE ;
}

savafile.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
savafile.Write((LPVOID) m_lpBMPHdr, size);
savafile.Write((LPVOID)(lpImageDest), m_dwImageSize);
savafile.Close();
delete[] lpImageDest;



这是应用代码,将YFY 所写代码封装在一个CDealWith类中
CDealWith m_DealWith ;

但执行后保存的dx.bmp是黑色的

调试其调用的两个成员函数(即PSAFreeCharToImageInit()、PSAFreeCharToImage())都成功了

不知道为什么

YFY 2008-02-21
  • 打赏
  • 举报
回复
加入以下定义:
LPBITMAPINFOHEADER m_lpVehicleBitmapHeader = NULL;
HDC m_hMemDC;
HBITMAP m_hBmp;
HBITMAP m_hBmpOld;
HFONT m_hFont;
HFONT m_hFontOld;
LPBYTE m_lpMemImage = NULL;
static bool m_bPermitAddCharToImage; // 字符叠加是否初始化的标记

根据你自己需要修改即可。
压缩成Jpeg可用Intel 的ijl15动态库。
YFY 2008-02-21
  • 打赏
  • 举报
回复
/************************************************************************
extern "C" EXPORTS Function PSAFreeCharToImage:
字符叠加在BMP图象数据上,通过创建MemDC方式写入
Input:
LPBYTE lpImage 需要进行字符叠加的BMP图像数据指针
LPCTSTR lpszLineFirstString 叠加的第一行字符
LPCTSTR lpszLineSecondString 叠加的第二行字符
LPCTSTR lpszLineThirdString 叠加的第三行字符
DWORD dwLineFirstStartPosX 第一行字符的起始X坐标
DWORD dwLineFirstStartPosY 第一行字符的起始Y坐标
DWORD dwLineSecondStartPosX 第二行字符的起始X坐标
DWORD dwLineSecondStartPosY 第二行字符的起始Y坐标
DWORD dwLineThirdStartPosX 第三行字符的起始X坐标
DWORD dwLineThirdStartPosY 第三行字符的起始Y坐标
Output:
LPBYTE lpImageDst 叠加字符后的BMP图像数据指针
return::
正常返回0值,非0值表示失败;
Update:
Author Date Ver Remark
Shimingjie 2005/04/06 1.0 Create
Shimingjie 2005/04/26 1.1 Add remark/Interface Complete
Shimingjie 2005/05/17 1.2 Change Function Mode && Parameter
************************************************************************/
extern "C" int PASCAL EXPORT PSAFreeCharToImage(LPBYTE lpImage,
LPBYTE lpImageDst,
LPCTSTR lpszLineFirstString,
LPCTSTR lpszLineSecondString,
LPCTSTR lpszLineThirdString,
DWORD dwLineFirstStartPosX,
DWORD dwLineFirstStartPosY,
DWORD dwLineSecondStartPosX,
DWORD dwLineSecondStartPosY,
DWORD dwLineThirdStartPosX,
DWORD dwLineThirdStartPosY)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

if (!m_bPermitAddCharToImage)
{
return -1;
}

int iTmp = 0;
int iStringLen = 0;
int iRetval = 0xFF;

//SetDIBits 函数将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里
//返回值:非零表示成功,零表示失败。
iTmp = SetDIBits(m_hMemDC,
m_hBmp,
0,
m_lpVehicleBitmapHeader->biHeight,
(LPVOID)lpImage,
(BITMAPINFO*)m_lpVehicleBitmapHeader,
DIB_RGB_COLORS);
if (iTmp == 0)
{
iRetval = iRetval & 0xFE; // 1111 1110
}

//TextOut 文本绘图函数。
//返回值:非零表示成功,零表示失败。
iStringLen = lstrlen(lpszLineFirstString);
if (iStringLen > 0)
{
TextOut(m_hMemDC, dwLineFirstStartPosX, dwLineFirstStartPosY, lpszLineFirstString, iStringLen);
}

iStringLen = lstrlen(lpszLineSecondString);
if (iStringLen > 0)
{
TextOut(m_hMemDC, dwLineSecondStartPosX, dwLineSecondStartPosY, lpszLineSecondString, iStringLen);
}

iStringLen = lstrlen(lpszLineThirdString);
if (iStringLen > 0)
{
TextOut(m_hMemDC, dwLineThirdStartPosX, dwLineThirdStartPosY, lpszLineThirdString, iStringLen);
}

//BYTE *pTemp = new BYTE[dwImageByte];
//ZeroMemory(pTemp, dwImageByte);

//GetDIBits 函数将来自一幅位图的二进制位复制到一幅与设备无关的位图里
//返回值:非零表示成功,零表示失败。
iTmp = GetDIBits(m_hMemDC,
m_hBmp,
0,
m_lpVehicleBitmapHeader->biHeight,
(LPVOID)lpImageDst,
(BITMAPINFO*)m_lpVehicleBitmapHeader,
DIB_RGB_COLORS);
//iTmp = GetBitmapBits(hBmp, dwImageByte,(LPVOID)lpImageDst);
if (iTmp == 0)
{
iRetval = iRetval & 0xFD; // 1111 1101
}

//如果字符叠加成功,那么返回值置0
if (iRetval == 0xFF)
{
iRetval = 0;
}

return (iRetval);
}

/************************************************************************
extern "C" EXPORTS Function PSAFreeCharToImageEnd:
释放在内存设备场景中进行字符叠加所申请的资源
Input:

Output:
正常返回非0值,0值表示失败;
Update:
Author Date Ver Remark
Shimingjie 2005/05/17 1.0 Create
************************************************************************/
extern "C" int PASCAL EXPORT PSAFreeCharToImageEnd()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

int iRetval = 0xFF;

SelectObject(m_hMemDC,m_hFontOld);

SelectObject(m_hMemDC, m_hBmpOld);

//DeleteObject 用这个函数删除GDI对象,比如画笔、刷子、字体、位图、区域以及调色板等等。
//对象使用的所有系统资源都会被释放
//返回值:非零表示成功,零表示失败。
DeleteObject(m_hBmp);

DeleteObject(m_hBmpOld);

DeleteObject(m_hFont);

DeleteObject(m_hFontOld);

//DeleteObject(hMemBmp);

DeleteDC(m_hMemDC);

if (m_lpMemImage != NULL)
{
delete[] m_lpMemImage;
m_lpMemImage = NULL;
}

if (m_lpVehicleBitmapHeader != NULL)
{
delete[] m_lpVehicleBitmapHeader;
m_lpVehicleBitmapHeader = NULL;
}

//如果终止成功,那么返回值置0
if (iRetval == 0xFF)
{
iRetval = 0;
}

m_bPermitAddCharToImage = false;

return (iRetval);
}


YFY 2008-02-21
  • 打赏
  • 举报
回复
通过创建虚拟的设备场景进行字符叠加。在Windows操作系统下运行,VC6编译,可以支持Windows已安装的字体。

/************************************************************************
extern "C" EXPORTS Function PSAFreeCharToImageInit:
初始化在内存设备场景中进行字符叠加
Input:
DWORD hDC 设备场景(根据此设备场景建立内存设备场景)
DWORD dwImgWidth 图象宽
DWORD dwImgHeight 图象高
LPCTSTR lpszFontName 叠加字符名称
int iFontSize 叠加字符的大小
DWORD dwFontBold 是否粗体
DWORD dwFontItalic 是否斜体
DWORD dwFontUnderline 是否加下划线
DWORD dwFontStrikeOut 是否加删除线
BYTE btColorB 叠加文字的颜色RGB值中的B
BYTE btColorG 叠加文字的颜色RGB值中的G
BYTE btColorR 叠加文字的颜色RGB值中的R
return:
正常返回0值,非0值表示失败;
Update:
Author Date Ver Remark
Shimingjie 2005/05/17 1.0 Create
************************************************************************/
extern "C" int PASCAL EXPORT PSAFreeCharToImageInit(DWORD hDC,
DWORD dwImageWidth,
DWORD dwImageHeight,
LPCTSTR lpszFontName,
int iFontSize,
DWORD dwFontBold,
DWORD dwFontItalic,
DWORD dwFontUnderline,
DWORD dwFontStrikeOut,
BYTE btForeColorB,
BYTE btForeColorG,
BYTE btForeColorR)

{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

DWORD dwImageByte = 0;
int iRetval = 0xFF;

dwImageByte = dwImageWidth * dwImageHeight * (DWORD)3; //计算BMP图像数据总大小

m_lpMemImage = (LPBYTE) new unsigned char[dwImageByte];

m_lpVehicleBitmapHeader = (LPBITMAPINFOHEADER) new char[40];

//BITMAPINFOHEADER 结构变量初始化
m_lpVehicleBitmapHeader->biBitCount = 24;
m_lpVehicleBitmapHeader->biClrImportant = 0;
m_lpVehicleBitmapHeader->biClrUsed = 0;
m_lpVehicleBitmapHeader->biCompression = 0;
m_lpVehicleBitmapHeader->biHeight = dwImageHeight;
m_lpVehicleBitmapHeader->biPlanes = 1;
m_lpVehicleBitmapHeader->biSize = 40;
m_lpVehicleBitmapHeader->biSizeImage = dwImageByte;
m_lpVehicleBitmapHeader->biWidth = dwImageWidth;
m_lpVehicleBitmapHeader->biXPelsPerMeter = 0;
m_lpVehicleBitmapHeader->biYPelsPerMeter = 0;

// CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景
// 返回值:执行成功返回新设备场景句柄,若出错则为零
// 注意点:不再需要时,该设备场景可用DeleteDC函数删除。
m_hMemDC = CreateCompatibleDC((HDC)hDC); //用DeleteDC删除句柄
if (m_hMemDC == 0)
{
iRetval = iRetval & 0xFE; // 1111 1110
}

//hMemDC = CreateDC("DISPLAY",NULL,NULL, NULL); //用DeleteDC删除句柄
//HDC hMemDC = GetDC(0); //用ReleaseDC释放句柄


// CreateDIBSection 创建一个DIBSection,这是一个GDI对象,可象一幅与设备有关位图那样使用。但是,它在内部作为一幅与设备无关位图保存。
// 返回值:执行成功返回DIBSection位图的句柄,零表示失败。
// 注意点:一旦不再需要,记住用DeleteObject函数删除DIBSection位图。

m_hBmp = CreateDIBSection(m_hMemDC,
(BITMAPINFO*)m_lpVehicleBitmapHeader,
DIB_RGB_COLORS,
(LPVOID*)&m_lpMemImage,
NULL,
0);

//hBmp = CreateCompatibleBitmap(hMemDC,lpVehicleBitmapHeader->biWidth,lpVehicleBitmapHeader->biHeight);
if (m_hBmp == 0)
{
iRetval = iRetval & 0xFD; // 1111 1101
}

//SelectObject 每个设备场景都可能有选入其中的图形对象。其中包括位图、刷子、字体、画笔以及区域等等。
// 一次选入设备场景的只能有一个对象。选定的对象会在设备场景的绘图操作中使用。
// 例如,当前选定的画笔决定了在设备场景中描绘的线段颜色及样式
//返回值:与以前选入设备场景的相同hObject类型的一个对象的句柄,零表示出错。
m_hBmpOld = (HBITMAP)SelectObject(m_hMemDC, m_hBmp);

//CreateFont 用指定的属性创建一种逻辑字体
//返回值:执行成功则返回逻辑字体的句柄,零表示失败。
if (dwFontBold > 0) //创建粗体的字符
{
m_hFont = CreateFont(iFontSize,0,0,0,FW_BOLD,dwFontItalic,dwFontUnderline,dwFontStrikeOut,DEFAULT_CHARSET,0,0,0,0,lpszFontName);
}
else
{
m_hFont = CreateFont(iFontSize,0,0,0,FW_THIN,dwFontItalic,dwFontUnderline,dwFontStrikeOut,DEFAULT_CHARSET,0,0,0,0,lpszFontName);
}
if (m_hFont == 0)
{
iRetval = iRetval & 0xFB; // 1111 1011
}

m_hFontOld = (HFONT)SelectObject(m_hMemDC, m_hFont);

//SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式
//返回值:文本色的前一个RGB颜色设定。CLR_INVALID表示失败。
SetBkMode(m_hMemDC, TRANSPARENT); //TRANSPARENT 表示透明处理,即不作上述填充
//OPAQUE 表示用当前的背景色填充虚线画笔、阴影刷子以及字符的空隙

//SetTextColor 设置当前文本颜色。这种颜色也称为“前景色”
//返回值:文本色的前一个RGB颜色设定。CLR_INVALID表示失败。
SetTextColor(m_hMemDC, RGB(btForeColorR, btForeColorG, btForeColorB));

//如果初始化成功,那么返回值0
if (iRetval == 0xFF)
{
iRetval = 0;
m_bPermitAddCharToImage = true;
}

return (iRetval);
}
lf426 2008-02-21
  • 打赏
  • 举报
回复
试试SDL。
http://lazyfoo.net/SDL_tutorials/lesson23/index.php
http://lazyfoo.net/SDL_tutorials/lesson30/index.php
电影魔方 Wizard“电影魔方”是品质优秀、功能强大、操作简单的多媒体数字视频编辑工具软件。它为我们打造了一个精彩、动态的数字电影创作和制作空间。无论您是初学者或资深用户,电影魔方都可以帮助您轻松完成素材剪切、影片编辑、特技处理、字幕创作、效果合成等工作,通过综合运用影像、声音、动画、图片、文字等素材资料,创作出各种不同用途的多媒体影片。 程序主要特色: 1.精美界面,自由组合,直观操作,轻松上手. 2.单帧编辑,精确定位,实时预览.双屏显示. 3.逆向播放,多级变速,精彩特技,丰富转场. 4.素材管理,图形绘制.字幕创作.效果合成. 5.完美支持MPEG-1及MPEG-2的输出格式 程序主要功能: 1.界面:自由组合的窗口模式;使用方便的项目及素材管理器;输入、输出双监视窗口;四个编辑轨道的时间轴; 2.预览:时间码准确定位;双监视窗口可同时预览或操作;在滑块拖动中实时预览;多级变速播放和逆向播放。 3.字幕:独立的字幕编辑器;快捷的字幕合成方式;丰富的图形绘制功能;16种字幕动态效果。 4.编辑:直观灵活的素材拖放操作;实用高效的编辑工具箱;支持音视频同步调整;精确到每帧的编辑精度。 5.转场:多种精彩转场特效;轻松调整转场长度;任意设定转场参数;提供音频转场效果。 6.输出:可输出MPEG-1、MPEG-2、VCD、SVCD等视频文件。 7.支持格式: 视频:.mpg、.mpeg、.mpv、.dat、.vob、.ts、avi; 音频:.mp1、.mp2、.mp3、.AC3、.wav 图像: .bmp、.jpg、.jpeg、.gif、.ico、.wmf。 真正可注册限时版序列号:MVW-MPEG2-TPQMZPBS01ZZPJ
超级转换秀11.8印心豪华破解版 《超级转换秀》是梦幻科技品牌旗下优秀力作。超级转换秀是国内首个集成视频转换、音频转换、CD抓轨、音视频混合转换、音视频切割/驳接转换、叠加视频水印、叠加滚动字幕/个性文字/图片等于一体的优秀影音转换工具。其内置国际一流的解压技术,转换质量一流,同时支持各种CPU的MMX,3D Now!,SSE1/2/3/4以及最新多核技术等指令系统的全面优化,让您拥有更快速的转换速度。其支持的功能之多,几乎可以满足您所有的转换要求并成为您的转换工具首选。其功能要点如下: 1.支持将CD音乐直接转换为WAV/MP3/WMA/OGG等数字音乐,并支持按用户喜好选择各种转换参数,支持批量转换处理,支持多光驱。 2.支持WAV,MP3,WMA,AAC,M4A,OGG,APE,AC3,RMA等格式的音频,同时支持抓取AVI,VCD,SVCD,DVD,MPG,WMV,ASF,RM,RMVB,FLV,F4V,MOV,QT,MP4,MPEG4,3GP,3G2,MKV,TS,TP,MTS,M2TS,MOD,TOD,SDP,YUV等视频文件的音频并转换,以上所有格式都可转换为WAV/MP3/WMA/AAC/M4A/OGG/APE等音频格式,音频转换均支持按您的喜好来设置相关转换参数,并支持批量转换处理。 3.支持将各主流视频AVI/VCD/SVCD/DVD/MPG/WMV/ASF/RM/RMVB/FLV/F4V/MOV/QT/MP4/MPEG4/3GP/3G2/MKV/TS/TP/MTS/M2TS/MOD/TOD/SDP/YUV等转换为AVI/MPEG4/VCD/SVCD/DVD/MPG/WMV/RM/RMVB/FLV/MOV/GIF闪图等格式。AVI格式允许任您选择十多种系统音频和视频压缩器,包括Divx/Xvid等MPEG4视频压缩器;MPG格式支持应用于家庭影碟机的VCD/SVCD/DVD之NTSC/PAL制式的转换或自定义MPEG1/MPEG2格式;WMV格式允许用户选择各种适应电脑观看、各种网络在线观看、手机或掌上设备观看等不同质量级别的转换画面并允许您选择自己定制的WMV转换参数文件(包括支持VC-1高清WMV编码);RM/RMVB格式支持各种网络带宽应用、手机移动设备应用等不同质量级别视频的导出。视频转换还支持不同视频文件和音频文件的混合合成转换,切割转换、合并转换等。允许为各导出格式选择屏幕缩放方法,并支持批量转换处理,甚至还可以允许您在最终视频的具体位置叠加自己半透明的个性文字、图片(水印)或滚动字幕视频效果! ● V11.8首次在音、视频转换中允许重复修改截取的转换时间段的起点和终点参数,让随时修改参数或切割修改更方便,不必由于时间段设置失误而每次都重新从头设置。 ● V11.8首次在音频转换中加入了激动人心的"专用混音器"功能,让混音成为可能!混音器支持多格式导入混音并支持将混音结果导出保存为音频文件,允许对每个输入音频源进行单独的音量混音设置 ● V11.8针对RM/RMVB视频转换中出现的错误和异常进行了更好的兼容,对新旧解码器进行了更好的支持(注:RM/RMVB新旧双解码内核只供正式用户此双解码内核)。 ● 解决了在批量处理过程中,由于某视频文件兼容性错误而导致全部转换意外中止的问题,针对批量转换加入了容错系统,确保转换顺利进行。同时解决了在批量处理中无法自动添加识别一些音频或视频格式的错误。 ● 解决了在音视频转换或切割同一视频或音频文件的转换中,目标文件名由于自动命名算法不完善导致覆盖之前生成的文件的重大错误,使得在切割或批量处理中更安全稳定。 ● 解决了CD转换参数设置无法保存的错误。 ● 对整体界面进行了总体改进和提高。 ● CD抓轨功能上全面彻底更换内核,新的内核免除ASPI的安装,免除了再重启系统的麻烦。再次全新CD转换内核异常强大:支持IDE/USB/SCSI/FireWire等几乎所有光驱的全面抓轨高性能转换;可直接从CD转为WAV/MP3/WMA/OGG等诸多格式,比原来支持格式更多,同时各种格式支持更详细的参数设置,由于增加了直接转换,让音质绝对一流;新的CD转换内核还采用了并发大面积光盘抓轨、集中转换、智能纠错等先进技术,使得转换速度达到目前CD转换真正最快最高水平! ● 在整个程序中引入了核心文件自动保护技术,并加强了安装程序和软件防干扰性能,确保从安装到软件的长久性运行的稳定和安全。 ● 对CD预览功能进行了全面加强,支持直接数字高速读取播放(免插音频线),支持数字频谱仪显示等人性化功能。 ● WMV视频导出功能增加了PDA常用的WMV 16:9宽屏幕转换配置文件,现在只需从程序安装路径的WMV配置文件保存目录里直接选取配置文件即可,免除自己设定的烦恼。 ● 全方位错误大修正:修正了修改按钮的显示错误;修正了光驱中放置空刻录碟导致程序启动失败的错误;修正了导出路径自动保存失效的错误。同时在程序界面上进行了彻底的改进和优化! ● 允许对转换列表中的已添加项目进行参数的重新编辑,大大节省了您的转换和操作效率。 ● 对输出文件夹进行自动记忆,免去每次都得指定的麻烦,操作更方便。 ● 对音频转换进行彻底的内核变更,解决了转换过程中由于文件名等问题导致某些文件无法顺利转换的诸多不稳定问题。 ● 在视频转换中增加允许自定义导出MPEG1或MPEG2的MPG视频。 ● 在音频转换中增加允许导出超优质AAC格式的文件,支持比特率可高达448kbps!(32-448kbps) ● 支持更多实用的导出格式:加入了MPG自定义格式支持,允许用户自定义设置MPG高度、宽度和视频比特率。 ● 修正了部分DVD转换参数识别异常导致的转换失败问题。 ● 修正了AVI导出时,无法判别视频宽度和高度以及帧速率的问题。 ● 修正了部分格式批量选取时导致的参数错误而引起的转换失败问题。 ● 加强了音频WMA和视频WMV的自动设置功能并修正了相关错误。 ● 修正了转换列表无法多选删除文件的错误,让操作更方便。 ● 加入了对MP4/3GP/SDP/YUV等MP4视频或手机3GPP视频格式的支持。 ● 重大修正了注册用户在转换过程中被提示无法批量处理的错误。 ● 加入了真正意义上完全由用户自定义的透明LOGO个性图标制作支持,支持格式多达:JPG/BMP/GIF/TIF/PNG等主流格式。 ● 修正了自定义透明个性图标无法兼容部分制图工具制作的图片的错误。 ● 修正了自定义透明个性图标无法更换的错误。 ● 加入了一次性即可大批量添加目录下所有音频、视频文件的功能。 ● 增加了音频、视频切割功能并允许视频文件的音轨、视频轨的混合切割。 ● 其他相关错误的修改和功能的完善。

65,199

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧