mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-22 07:14:15 +08:00
style: Change files encoding format to UTF8-BOM
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Bmp2Video.h"
|
||||
|
||||
#define USE_JPEG 0
|
||||
@@ -67,11 +67,11 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
return ERR_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>BITMAPINFO<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MJPEG
|
||||
// 创建正确的BITMAPINFO用于MJPEG
|
||||
BITMAPINFO bmiFormat = *lpbmi;
|
||||
|
||||
if (m_fccHandler == ENCODER_H264) {
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>H.264ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 打开H.264压缩器
|
||||
m_hic = ICOpen(ICTYPE_VIDEO, mmioFOURCC('X', '2', '6', '4'), ICMODE_COMPRESS);
|
||||
if (!m_hic) {
|
||||
AVIFileRelease(m_pfile);
|
||||
@@ -79,7 +79,7 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
return ERR_NO_ENCODER;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>δѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>24λBMP<EFBFBD><EFBFBD>
|
||||
// 设置输入格式(未压缩的24位BMP)
|
||||
BITMAPINFOHEADER inputFormat = { 0 };
|
||||
inputFormat.biSize = sizeof(BITMAPINFOHEADER);
|
||||
inputFormat.biWidth = m_width;
|
||||
@@ -89,11 +89,11 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
inputFormat.biCompression = BI_RGB;
|
||||
inputFormat.biSizeImage = m_width * m_height * 3;
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>H.264ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 设置输出格式(H.264压缩)
|
||||
BITMAPINFOHEADER outputFormat = inputFormat;
|
||||
outputFormat.biCompression = mmioFOURCC('X', '2', '6', '4');
|
||||
|
||||
// <EFBFBD><EFBFBD>ѯѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||
// 查询压缩器能否处理这个格式
|
||||
DWORD result = ICCompressQuery(m_hic, &inputFormat, &outputFormat);
|
||||
if (result != ICERR_OK) {
|
||||
ICClose(m_hic);
|
||||
@@ -104,7 +104,7 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
return ERR_NO_ENCODER;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD>ʼѹ<EFBFBD><EFBFBD>
|
||||
// 开始压缩
|
||||
result = ICCompressBegin(m_hic, &inputFormat, &outputFormat);
|
||||
if (result != ICERR_OK) {
|
||||
ICClose(m_hic);
|
||||
@@ -115,22 +115,22 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
return ERR_NO_ENCODER;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 设置质量
|
||||
m_quality = 7500;
|
||||
|
||||
// AVI<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// AVI流配置
|
||||
bmiFormat.bmiHeader.biCompression = mmioFOURCC('X', '2', '6', '4');
|
||||
bmiFormat.bmiHeader.biBitCount = 24;
|
||||
bmiFormat.bmiHeader.biSizeImage = m_width * m_height * 3;
|
||||
m_si.dwSuggestedBufferSize = bmiFormat.bmiHeader.biSizeImage;
|
||||
} else if (m_fccHandler == ENCODER_MJPEG) {
|
||||
// MJPEG<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// MJPEG需要特殊设置
|
||||
bmiFormat.bmiHeader.biCompression = mmioFOURCC('M', 'J', 'P', 'G');
|
||||
bmiFormat.bmiHeader.biBitCount = 24; // MJPEG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>24λ
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
||||
bmiFormat.bmiHeader.biBitCount = 24; // MJPEG解码后是24位
|
||||
// 计算正确的图像大小
|
||||
bmiFormat.bmiHeader.biSizeImage = m_width * m_height * 3;
|
||||
m_si.dwSuggestedBufferSize = bmiFormat.bmiHeader.biSizeImage * 2; // Ԥ<EFBFBD><EFBFBD><EFBFBD>㹻<EFBFBD>ռ<EFBFBD>
|
||||
m_quality = 85; // Ĭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_si.dwSuggestedBufferSize = bmiFormat.bmiHeader.biSizeImage * 2; // 预留足够空间
|
||||
m_quality = 85; // 默认质量
|
||||
} else {
|
||||
m_si.dwSuggestedBufferSize = lpbmi->bmiHeader.biSizeImage;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
}
|
||||
|
||||
#if USE_JPEG
|
||||
// <EFBFBD>Ż<EFBFBD><EFBFBD><EFBFBD>BMP<EFBFBD><EFBFBD>JPEGת<EFBFBD><EFBFBD>
|
||||
// 优化的BMP到JPEG转换
|
||||
bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned char** jpegData, unsigned long* jpegSize)
|
||||
{
|
||||
if (!lpBuffer || !jpegData || !jpegSize) {
|
||||
@@ -175,29 +175,29 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned cha
|
||||
return false;
|
||||
}
|
||||
|
||||
// ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD>
|
||||
// 确保质量在合理范围内
|
||||
if (quality < 1) quality = 85;
|
||||
if (quality > 100) quality = 100;
|
||||
|
||||
int pitch = width * 3; // BGR24<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>
|
||||
int pitch = width * 3; // BGR24格式,每行字节数
|
||||
|
||||
// <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ΪNULL<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TurboJPEG<EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
// 重要:初始化为NULL,让TurboJPEG自己分配内存
|
||||
*jpegData = NULL;
|
||||
*jpegSize = 0;
|
||||
|
||||
// ȥ<EFBFBD><EFBFBD>TJFLAG_NOREALLOC<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TurboJPEG<EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
// 去掉TJFLAG_NOREALLOC标志,让TurboJPEG自动分配内存
|
||||
int tjError = tjCompress2(
|
||||
jpegCompressor,
|
||||
(unsigned char*)lpBuffer,
|
||||
width,
|
||||
pitch, // ÿ<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>
|
||||
pitch, // 每行字节数
|
||||
height,
|
||||
TJPF_BGR, // BGR<EFBFBD><EFBFBD>ʽ
|
||||
jpegData, // TurboJPEG<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
TJPF_BGR, // BGR格式
|
||||
jpegData, // TurboJPEG会自动分配内存
|
||||
jpegSize,
|
||||
TJSAMP_422, // 4:2:2ɫ<EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD>
|
||||
quality, // ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
0 // <EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
TJSAMP_422, // 4:2:2色度子采样
|
||||
quality, // 压缩质量
|
||||
0 // 不使用特殊标志
|
||||
);
|
||||
|
||||
if (tjError != 0) {
|
||||
@@ -208,7 +208,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned cha
|
||||
|
||||
tjDestroy(jpegCompressor);
|
||||
|
||||
// <EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 验证输出
|
||||
if (*jpegData == NULL || *jpegSize == 0) {
|
||||
Mprintf("JPEG compression produced no data\n");
|
||||
return false;
|
||||
@@ -226,9 +226,9 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned cha
|
||||
|
||||
using namespace Gdiplus;
|
||||
|
||||
// ==================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ====================
|
||||
// ==================== 辅助函数 ====================
|
||||
|
||||
// <EFBFBD><EFBFBD>ȡ JPEG <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CLSID
|
||||
// 获取 JPEG 编码器的 CLSID
|
||||
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
|
||||
{
|
||||
UINT num = 0;
|
||||
@@ -254,7 +254,7 @@ int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ==================== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ====================
|
||||
// ==================== 主函数 ====================
|
||||
|
||||
bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
unsigned char** jpegData, unsigned long* jpegSize)
|
||||
@@ -263,17 +263,17 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> DIB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>ֽڶ<EFBFBD><EFBFBD>룩
|
||||
// 计算 DIB 的行字节数(4字节对齐)
|
||||
int rowSize = ((width * 3 + 3) / 4) * 4;
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> Bitmap <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>24λ BGR <EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>
|
||||
// 创建 Bitmap 对象(24位 BGR 格式)
|
||||
Bitmap* bitmap = new Bitmap(width, height, PixelFormat24bppRGB);
|
||||
if (!bitmap || bitmap->GetLastStatus() != Ok) {
|
||||
if (bitmap) delete bitmap;
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> Bitmap <EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 锁定 Bitmap 以写入数据
|
||||
BitmapData bitmapData;
|
||||
Rect rect(0, 0, width, height);
|
||||
Status status = bitmap->LockBits(&rect, ImageLockModeWrite,
|
||||
@@ -284,12 +284,12 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ע<EFBFBD>⣺DIB <20>ǵײ<C7B5><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ת<EFBFBD><D7AA>
|
||||
// 复制数据(注意:DIB 是底部到顶部,需要翻转)
|
||||
BYTE* srcData = (BYTE*)lpBuffer;
|
||||
BYTE* dstData = (BYTE*)bitmapData.Scan0;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
// DIB <EFBFBD>Ǵӵײ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ת
|
||||
// DIB 是从底部开始的,所以需要翻转
|
||||
BYTE* srcRow = srcData + (height - 1 - y) * rowSize;
|
||||
BYTE* dstRow = dstData + y * bitmapData.Stride;
|
||||
memcpy(dstRow, srcRow, width * 3);
|
||||
@@ -297,14 +297,14 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
|
||||
bitmap->UnlockBits(&bitmapData);
|
||||
|
||||
// <EFBFBD><EFBFBD>ȡ JPEG <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 获取 JPEG 编码器
|
||||
CLSID jpegClsid;
|
||||
if (GetEncoderClsid(L"image/jpeg", &jpegClsid) < 0) {
|
||||
delete bitmap;
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> JPEG <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 设置 JPEG 质量参数
|
||||
EncoderParameters encoderParams;
|
||||
encoderParams.Count = 1;
|
||||
encoderParams.Parameter[0].Guid = EncoderQuality;
|
||||
@@ -314,7 +314,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
ULONG qualityValue = (ULONG)quality;
|
||||
encoderParams.Parameter[0].Value = &qualityValue;
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><EFBFBD><EFBFBD> JPEG
|
||||
// 创建内存流用于保存 JPEG
|
||||
IStream* stream = NULL;
|
||||
HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
if (FAILED(hr)) {
|
||||
@@ -322,7 +322,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ JPEG
|
||||
// 保存为 JPEG
|
||||
status = bitmap->Save(stream, &jpegClsid, &encoderParams);
|
||||
delete bitmap;
|
||||
|
||||
@@ -331,7 +331,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD>ȡ JPEG <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 获取 JPEG 数据
|
||||
HGLOBAL hMem = NULL;
|
||||
hr = GetHGlobalFromStream(stream, &hMem);
|
||||
if (FAILED(hr)) {
|
||||
@@ -345,11 +345,11 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 分配输出缓冲区
|
||||
*jpegSize = (unsigned long)memSize;
|
||||
*jpegData = new unsigned char[*jpegSize];
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 复制数据
|
||||
void* pMem = GlobalLock(hMem);
|
||||
if (pMem) {
|
||||
memcpy(*jpegData, pMem, *jpegSize);
|
||||
@@ -365,7 +365,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== GDI+ <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD> ====================
|
||||
// ==================== GDI+ 初始化/清理 ====================
|
||||
|
||||
class GdiplusManager
|
||||
{
|
||||
@@ -395,23 +395,23 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// ȫ<EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 全局对象,自动初始化和清理
|
||||
static GdiplusManager g_gdiplusManager;
|
||||
#endif
|
||||
|
||||
|
||||
// <EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>32λת24λת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>
|
||||
// 正确的32位转24位转换(含翻转)
|
||||
unsigned char* ConvertScreenshot32to24(unsigned char* p32bitBmp, int width, int height)
|
||||
{
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>BMP<EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>С<EFBFBD><EFBFBD>4<EFBFBD>ֽڶ<EFBFBD><EFBFBD>룩
|
||||
// 计算BMP的实际行大小(4字节对齐)
|
||||
int srcRowSize = ((width * 32 + 31) / 32) * 4;
|
||||
int dstRowSize = width * 3; // Ŀ<EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD>յ<EFBFBD>24λ
|
||||
int dstRowSize = width * 3; // 目标是紧凑的24位
|
||||
|
||||
unsigned char* p24bitBmp = (unsigned char*)malloc(dstRowSize * height);
|
||||
if (!p24bitBmp) return nullptr;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
// BMP<EFBFBD>Ǵ<EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD>ϴ洢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ת
|
||||
// BMP是从下到上存储,需要翻转
|
||||
unsigned char* src = p32bitBmp + (height - 1 - y) * srcRowSize;
|
||||
unsigned char* dst = p24bitBmp + y * dstRowSize;
|
||||
|
||||
@@ -419,25 +419,25 @@ unsigned char* ConvertScreenshot32to24(unsigned char* p32bitBmp, int width, int
|
||||
dst[x * 3 + 0] = src[x * 4 + 0]; // B
|
||||
dst[x * 3 + 1] = src[x * 4 + 1]; // G
|
||||
dst[x * 3 + 2] = src[x * 4 + 2]; // R
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Alphaͨ<EFBFBD><EFBFBD>
|
||||
// 忽略Alpha通道
|
||||
}
|
||||
}
|
||||
|
||||
return p24bitBmp;
|
||||
}
|
||||
|
||||
// 24λBMP<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD>룩
|
||||
// 24位BMP处理(含翻转和去对齐)
|
||||
unsigned char* Process24BitBmp(unsigned char* lpBuffer, int width, int height)
|
||||
{
|
||||
// BMP 24λ<EFBFBD>д<EFBFBD>С<EFBFBD><EFBFBD>4<EFBFBD>ֽڶ<EFBFBD><EFBFBD>룩
|
||||
// BMP 24位行大小(4字节对齐)
|
||||
int srcRowSize = ((width * 24 + 31) / 32) * 4;
|
||||
int dstRowSize = width * 3; // <EFBFBD><EFBFBD><EFBFBD>ո<EFBFBD>ʽ
|
||||
int dstRowSize = width * 3; // 紧凑格式
|
||||
|
||||
unsigned char* processed = (unsigned char*)malloc(dstRowSize * height);
|
||||
if (!processed) return nullptr;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
// <EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
// 翻转并去除填充字节
|
||||
unsigned char* src = lpBuffer + (height - 1 - y) * srcRowSize;
|
||||
unsigned char* dst = processed + y * dstRowSize;
|
||||
memcpy(dst, src, dstRowSize);
|
||||
@@ -475,7 +475,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
return false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>ĸ<EFBFBD>ʽͷ
|
||||
// 创建正确的格式头
|
||||
BITMAPINFOHEADER inputHeader = { 0 };
|
||||
inputHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
inputHeader.biWidth = m_width;
|
||||
@@ -488,7 +488,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
BITMAPINFOHEADER outputHeader = inputHeader;
|
||||
outputHeader.biCompression = mmioFOURCC('X', '2', '6', '4');
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 分配输出缓冲区
|
||||
DWORD maxCompressedSize = m_width * m_height * 3;
|
||||
unsigned char* compressedData = (unsigned char*)malloc(maxCompressedSize);
|
||||
if (!compressedData) {
|
||||
@@ -499,21 +499,21 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
|
||||
DWORD flags = 0;
|
||||
|
||||
// <EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ICCompress
|
||||
// 正确调用ICCompress
|
||||
DWORD result = ICCompress(
|
||||
m_hic, // ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
0, // <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD>0=<3D>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD>֡<EFBFBD><D6A1>
|
||||
&outputHeader, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽͷ
|
||||
compressedData, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
&inputHeader, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽͷ
|
||||
processedBuffer, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_hic, // 压缩器句柄
|
||||
0, // 标志(0=自动决定关键帧)
|
||||
&outputHeader, // 输出格式头
|
||||
compressedData, // 输出数据
|
||||
&inputHeader, // 输入格式头
|
||||
processedBuffer, // 输入数据
|
||||
NULL, // ckid
|
||||
&flags, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
m_nFrames, // ֡<EFBFBD><EFBFBD>
|
||||
0, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>0=<3D>Զ<EFBFBD><D4B6><EFBFBD>
|
||||
m_quality, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
NULL, // ǰһ֡<EFBFBD><EFBFBD>ʽͷ
|
||||
NULL // ǰһ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
&flags, // 输出标志
|
||||
m_nFrames, // 帧号
|
||||
0, // 期望大小(0=自动)
|
||||
m_quality, // 质量
|
||||
NULL, // 前一帧格式头
|
||||
NULL // 前一帧数据
|
||||
);
|
||||
|
||||
if (result != ICERR_OK) {
|
||||
@@ -523,7 +523,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
return false;
|
||||
}
|
||||
|
||||
// ʵ<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>outputHeader.biSizeImage<EFBFBD><EFBFBD>
|
||||
// 实际压缩大小在outputHeader.biSizeImage中
|
||||
writeData = compressedData;
|
||||
writeSize = outputHeader.biSizeImage;
|
||||
needFree = true;
|
||||
@@ -535,7 +535,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
case ENCODER_MJPEG: {
|
||||
unsigned char* processedBuffer = nullptr;
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬλ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// 处理不同位深度
|
||||
if (m_bitCount == 32) {
|
||||
processedBuffer = ConvertScreenshot32to24(lpBuffer, m_width, m_height);
|
||||
} else if (m_bitCount == 24) {
|
||||
@@ -545,7 +545,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
if (!processedBuffer) {
|
||||
return false;
|
||||
}
|
||||
// ѹ<EFBFBD><EFBFBD>ΪJPEG
|
||||
// 压缩为JPEG
|
||||
if (!BmpToJpeg(processedBuffer, m_width, m_height, m_quality, &writeData, &writeSize)) {
|
||||
free(processedBuffer);
|
||||
Mprintf("Failed to compress JPEG\n");
|
||||
@@ -560,7 +560,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
return false;
|
||||
}
|
||||
|
||||
// д<EFBFBD><EFBFBD>AVI<EFBFBD><EFBFBD>
|
||||
// 写入AVI流
|
||||
LONG bytesWritten = 0;
|
||||
LONG samplesWritten = 0;
|
||||
HRESULT hr = AVIStreamWrite(m_pavi, m_nFrames, 1,
|
||||
|
||||
Reference in New Issue
Block a user