1 #include "stdafx.h" 2 #include "GaussBlur.h" 3 4 5 CGaussBlur::CGaussBlur() 6 { 7 } 8 9 10 CGaussBlur::~CGaussBlur() 11 { 12 if (m_pTempl != NULL) 13 free(m_pTempl); 14 } 15 16 void CGaussBlur::SetSigma(double sigma) 17 { 18 int i; 19 m_sigma = sigma; 20 m_r = (int)(m_sigma * 3 + 0.5); 21 if (m_r <= 0) m_r = 1; 22 23 //����ģ�� 24 LPVOID pOldTempl = m_pTempl; 25 m_pTempl = (double*)realloc(m_pTempl, sizeof(double) * (m_r + 1)); 26 27 //����ʧ�ܣ� 28 if (m_pTempl == NULL) 29 { 30 if (pOldTempl != NULL) 31 free(pOldTempl); 32 33 return; 34 } 35 36 //���� p[0] �Ҷ�ֵΪ1 ��ģ���� 37 double k1 = (double)((-0.5) / (m_sigma * m_sigma)); 38 for (i = 0; i <= m_r; i++) 39 m_pTempl[i] = exp(k1 * i * i); 40 41 //����ģ���Ȩ�ܺ� 42 double sum = m_pTempl[0]; 43 for (i = 1; i <= m_r; i++) 44 { 45 sum += (m_pTempl[i] * 2); 46 } 47 48 //��һ�� 49 sum = (double)(1.0 / sum); //ȡ���� 50 for (i = 0; i <= m_r; i++) 51 m_pTempl[i] *= sum; 52 } 53 54 void CGaussBlur::Reset() 55 { 56 m_r = -1; 57 m_sigma = (double)(-1.0); 58 if (m_pTempl != NULL) 59 { 60 free(m_pTempl); 61 m_pTempl = NULL; 62 } 63 } 64 65 void CGaussBlur::DoGaussBlur(const CImage & image_src, CImage & image_dest) 66 { 67 if (image_src.IsNull()) 68 return; 69 int width = image_src.GetWidth(); 70 int height = image_src.GetHeight(); 71 int bpp = image_src.GetBPP(); 72 if (!image_dest.IsNull()) 73 image_dest.Destroy(); 74 image_dest.Create(width, height, bpp); 75 Filter(image_src.GetPixelAddress(0, height - 1), image_dest.GetPixelAddress(0, height - 1), width, height, bpp); 76 } 77 78 bool CGaussBlur::Filter(LPCVOID pSrc, LPVOID pDest, int width, int height, int bpp) 79 { 80 if (pSrc == NULL || pDest == NULL) 81 return false; 82 83 //ֻ�ܴ��� 8, 24�� 32 bpp 84 if (bpp != 24 && bpp != 8 && bpp != 32) 85 return false; 86 87 if (m_r < 0 || m_pTempl == NULL) 88 return false; 89 90 int absHeight = (height >= 0) ? height : (-height); 91 int stride = (width * bpp + 31) / 32 * 4; 92 int pixelSize = bpp / 8; 93 94 //���뻺�������洢�м��� 95 LPVOID pTemp = malloc(stride * absHeight); 96 if (pTemp == NULL) 97 return false; 98 99 CGaussBlurThreadParams params; 100 101 params.pSrc = (LPBYTE)pSrc; 102 params.pDest = (LPBYTE)pTemp; 103 params.width = width; 104 params.height = absHeight; 105 params.stride = stride; 106 params.pixelSize = pixelSize; 107 params.r = m_r; 108 params.pTempl = m_pTempl; 109 params.rowBegin = 0; 110 params.rowEnd = absHeight; 111 params.bHorz = true; 112 113 if (bpp == 8) 114 GaussBlurThreadProc8(¶ms); 115 else 116 GaussBlurThreadProc24(¶ms); 117 118 119 params.pSrc = (LPBYTE)pTemp; 120 params.pDest = (LPBYTE)pDest; 121 params.bHorz = false; 122 123 if (bpp == 8) 124 GaussBlurThreadProc8(¶ms); 125 else 126 GaussBlurThreadProc24(¶ms); 127 128 free(pTemp); 129 return true; 130 } 131 132 DWORD CGaussBlur::GaussBlurThreadProc8(LPVOID lpParameters) 133 { 134 CGaussBlurThreadParams *pInfo = (CGaussBlurThreadParams*)lpParameters; 135 136 double result; 137 int row, col, subRow, subCol, MaxVal, x, x1; 138 LPINT pSubVal, pRefVal; 139 140 if (pInfo->bHorz) 141 { 142 //ˮƽ���� 143 pSubVal = &subCol; 144 pRefVal = &col; 145 MaxVal = pInfo->width - 1; 146 } 147 else 148 { 149 //��ֱ���� 150 pSubVal = &subRow; 151 pRefVal = &row; 152 MaxVal = pInfo->height - 1; 153 } 154 155 LPBYTE pSrcPixel = NULL; 156 LPBYTE pDestPixel = NULL; 157 158 for (row = pInfo->rowBegin; row < pInfo->rowEnd; ++row) 159 { 160 for (col = 0; col < pInfo->width; ++col) 161 { 162 pDestPixel = pInfo->pDest + pInfo->stride * row + col; 163 164 result = 0; 165 166 subRow = row; 167 subCol = col; 168 169 for (x = -pInfo->r; x <= pInfo->r; x++) 170 { 171 //�߽紦�� 172 x1 = (x >= 0) ? x : (-x); 173 *pSubVal = *pRefVal + x; 174 if (*pSubVal < 0) *pSubVal = 0; 175 else if (*pSubVal > MaxVal) *pSubVal = MaxVal; 176 177 pSrcPixel = pInfo->pSrc + pInfo->stride * subRow + subCol; 178 179 result += *pSrcPixel * pInfo->pTempl[x1]; 180 } 181 *pDestPixel = (BYTE)result; 182 } 183 } 184 return 0; 185 } 186 187 DWORD CGaussBlur::GaussBlurThreadProc24(LPVOID lpParameters) 188 { 189 CGaussBlurThreadParams *pInfo = (CGaussBlurThreadParams*)lpParameters; 190 191 double result[3]; 192 int row, col, subRow, subCol, MaxVal, x, x1; 193 LPINT pSubVal, pRefVal; 194 195 if (pInfo->bHorz) 196 { 197 //ˮƽ���� 198 pSubVal = &subCol; 199 pRefVal = &col; 200 MaxVal = pInfo->width - 1; 201 } 202 else 203 { 204 //��ֱ���� 205 pSubVal = &subRow; 206 pRefVal = &row; 207 MaxVal = pInfo->height - 1; 208 } 209 210 LPBYTE pSrcPixel = NULL; 211 LPBYTE pDestPixel = NULL; 212 213 for (row = pInfo->rowBegin; row < pInfo->rowEnd; ++row) 214 { 215 for (col = 0; col < pInfo->width; ++col) 216 { 217 pDestPixel = pInfo->pDest + pInfo->stride * row + pInfo->pixelSize * col; 218 219 result[0] = 0; 220 result[1] = 0; 221 result[2] = 0; 222 223 subRow = row; 224 subCol = col; 225 226 for (x = -pInfo->r; x <= pInfo->r; x++) 227 { 228 x1 = (x >= 0) ? x : (-x); 229 *pSubVal = *pRefVal + x; 230 231 //�߽紦��Photoshop ���õ��Ƿ���1�� 232 //����1��ȡ��Ե���أ�ͼ���Ե�������ڲ���ɢ���� 233 if (*pSubVal < 0) *pSubVal = 0; 234 else if (*pSubVal > MaxVal) *pSubVal = MaxVal; 235 236 //����2��ȡ��ǰ���أ�ʹ��Խ����ͼ���Ե�ĵط�Խ������ 237 /* 238 if(*pSubVal < 0 || *pSubVal > MaxVal) 239 *pSubVal = *pRefVal; 240 */ 241 242 pSrcPixel = pInfo->pSrc + pInfo->stride * subRow + pInfo->pixelSize * subCol; 243 244 result[0] += pSrcPixel[0] * pInfo->pTempl[x1]; 245 result[1] += pSrcPixel[1] * pInfo->pTempl[x1]; 246 result[2] += pSrcPixel[2] * pInfo->pTempl[x1]; 247 } 248 pDestPixel[0] = (BYTE)result[0]; 249 pDestPixel[1] = (BYTE)result[1]; 250 pDestPixel[2] = (BYTE)result[2]; 251 } 252 } 253 return 0; 254 } 255