![]()
#include <windows.h>
HANDLE WINAPI BIPImgSoften(HANDLE hDib, long soften = 8) {
if (!hDib || soften <= -8) return NULL;
// 锁定 DIB 句柄,获取 BITMAPINFOHEADER
BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*)GlobalLock(hDib);
if (!pBIH) return NULL;
int width = pBIH->biWidth;
int height = abs(pBIH->biHeight);
int bitCount = pBIH->biBitCount;
int bytesPerPixel = bitCount / 8; // 每像素字节数(一般 3 或 4)
int rowSize = ((width * bitCount + 31) / 32) * 4;
int imageSize = rowSize * height;
// 创建新的 DIB 内存
HANDLE hNewDib = GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + imageSize);
if (!hNewDib) {
GlobalUnlock(hDib);
return NULL;
}
// 锁定新 DIB,获取 BITMAPINFOHEADER
BITMAPINFOHEADER* pNewBIH = (BITMAPINFOHEADER*)GlobalLock(hNewDib);
if (!pNewBIH) {
GlobalFree(hNewDib);
GlobalUnlock(hDib);
return NULL;
}
// 复制头部信息
*pNewBIH = *pBIH;
BYTE* pSrcData = (BYTE*)(pBIH + 1);
BYTE* pDstData = (BYTE*)(pNewBIH + 1);
// 计算模糊核的权重
int kernelSize = 3;
int kernelSum = (soften + 9); // 核的归一化系数
int kernel[3][3] = {
{ 1, 1, 1 },
{ 1, soften, 1 },
{ 1, 1, 1 }
};
// 遍历图像像素(忽略边界)
for (int y = 1; y < height - 1; y++) {
for (int x = 1; x < width - 1; x++) {
for (int c = 0; c < bytesPerPixel; c++) {
int sum = 0;
// 计算 3×3 卷积区域
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
int pixelOffset = ((y + ky) * rowSize) + ((x + kx) * bytesPerPixel) + c;
sum += pSrcData[pixelOffset] * kernel[ky + 1][kx + 1];
}
}
// 归一化处理,防止像素值溢出
int pixelOffset = (y * rowSize) + (x * bytesPerPixel) + c;
pDstData[pixelOffset] = min(255, max(0, sum / kernelSum));
}
}
}
// 处理边界(简单复制原图像)
memcpy(pDstData, pSrcData, rowSize); // 复制第一行
memcpy(pDstData + (height - 1) * rowSize, pSrcData + (height - 1) * rowSize, rowSize); // 复制最后一行
for (int y = 0; y < height; y++) {
int rowOffset = y * rowSize;
memcpy(pDstData + rowOffset, pSrcData + rowOffset, bytesPerPixel); // 复制左侧像素
memcpy(pDstData + rowOffset + (width - 1) * bytesPerPixel,
pSrcData + rowOffset + (width - 1) * bytesPerPixel, bytesPerPixel); // 复制右侧像素
}
// 解锁 DIB
GlobalUnlock(hDib);
GlobalUnlock(hNewDib);
return hNewDib;
}
你是对的,在上面的代码中,soften 变量没有真正影响模糊效果。我们可以使用 soften 值来调整模糊核的权重,使其产生不同程度的模糊效果。以下是修正后的代码:
📌 关键修改
-
调整模糊核的强度
- 之前的
3×3 均值滤波器使用的是固定的均值 1/9。
- 现在
soften 变量用于调整核的强度: 1(soften+9)[1111soften1111]\frac{1}{(soften + 9)} \begin{bmatrix} 1 & 1 & 1 \\ 1 & soften & 1 \\ 1 & 1 & 1 \end{bmatrix}(soften+9)11111soften1111
soften 取值范围 > -8,当 soften = 8 时,中心权重大,边缘影响较小,减少模糊程度。
- 当
soften 越小(接近 -8),则所有像素更平均参与计算,使图像更加模糊。
-
优化循环计算
- 直接在
for 循环中应用 soften 控制模糊权重,而不是固定的均值滤波。
✅ 修正后代码
📌 关键改进
✅ soften 变量真正影响模糊程度
soften > 0:中心像素影响更大,边缘像素影响小,减少模糊感。
soften < 0:所有像素均匀加权,增强模糊效果。
✅ 避免固定的 1/9 平均值,可以动态控制模糊核的中心权重。
✅ 边界像素复制,防止模糊后边缘出现黑边。
🚀 进一步优化
-
改进 soften 取值范围
- 目前
soften > -8,可以进一步放宽,或者动态计算更大的模糊核(如 5×5)。
-
高斯模糊
- 目前是 均值模糊,可以使用 高斯核,模糊更自然: [121242121]\begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix}121242121 归一化后除以
16,实现更平滑的模糊。
-
SIMD 加速
- 使用
SSE / AVX 进行 向量化计算,提高处理速度。
🎯 结果
- 模糊效果增强:
soften 变量现在可以 真正影响模糊程度。
- 适用于 24-bit / 32-bit DIB,并保持
RGB 色彩信息。
- 边界复制修复,防止边缘变黑。