边缘抖动示例代码:
- void* WaterColorThread(void *arg)
- {
- WaterColorInfo *watercolor_info = (WaterColorInfo *)arg;
- BMPINFO *pSrcBitmap = watercolor_info->pSrcBitmap;
- BMPINFO *pPaperBitmap = watercolor_info->pPaperBitmap;
- float *noise_perlin = watercolor_info->noise_perlin;
- float *mean = watercolor_info->mean;
- float *stdev = watercolor_info->stdev;
- int color_index = watercolor_info->color_index;
- int thread_id = watercolor_info->thread_id;
- int block_count = watercolor_info->block_count;
- // 数据转换
- int width = pSrcBitmap->lWidth;
- int height= pSrcBitmap->lHeight;
- int size = width*height;
- float *rdata = (float *)malloc(size * sizeof(float));
- float *gdata = (float *)malloc(size * sizeof(float));
- float *bdata = (float *)malloc(size * sizeof(float));
- ConvertToFloat(pSrcBitmap, rdata, gdata, bdata);
- // 简化细节
- Abstraction(rdata, gdata, bdata, mean, stdev, width, height, color_index, thread_id);
- // 边缘抖动
- EdgeWobbling(rdata, gdata, bdata, noise_perlin, width, height, block_count);
- // 边缘加深
- EdgeDarkening(rdata, gdata, bdata, 1.5f, width, height);
- // 颜料分散
- PigmentDispersion(rdata, gdata, bdata, 0.5f, width, height);
- // 紊流效果
- TurbulenceFlow(rdata, gdata, bdata, noise_perlin, 2.0f, width, height);
- // 纸张纹理
- PaperTexture(rdata, gdata, bdata, pPaperBitmap, 0.225f, width, height);
- // 数据转换
- ConvertToUchar(rdata, gdata, bdata, pSrcBitmap);
- // 效果微调
- ImageAdjust(pSrcBitmap);
- free(rdata);
- free(gdata);
- free(bdata);
- rdata = NULL;
- gdata = NULL;
- bdata = NULL;
- return NULL;
- }
边缘加深示例代码:
- void EdgeWobbling(float * rdata, float * gdata, float * bdata, float * noise_perlin, int width, int height, int block_count) {
- int size = width * height;
- float strengthx = width / 3.5f;
- float strengthy = height * block_count / 3.5f;
- float strength = MAX(strengthx, strengthy);
- float * rcopy = (float * ) malloc(size * sizeof(float));
- float * gcopy = (float * ) malloc(size * sizeof(float));
- float * bcopy = (float * ) malloc(size * sizeof(float));
- memcpy(rcopy, rdata, size * sizeof(float));
- memcpy(gcopy, gdata, size * sizeof(float));
- memcpy(bcopy, bdata, size * sizeof(float));
- int index = 0,
- new_index = 0;
- int p_offsetx = 0,
- p_offsety = 0,
- border_w = width - 1,
- border_h = height - 1;
- float * pNoiseData = noise_perlin;
- for (int i = 0; i < height - 1; i++) {
- for (int j = 0; j < width - 1; j++) {
- index = i * width + j;
- pNoiseData = noise_perlin + index;
- float new_posx = CLAMP0255_XY(j + ( * (pNoiseData + 1) - *pNoiseData) * strength, border_w);
- float new_posy = CLAMP0255_XY(i + ( * (pNoiseData + width) - *pNoiseData) * strength, border_h);
- int n_posx = (int) new_posx;
- int n_posy = (int) new_posy;
- float dx = new_posx - n_posx;
- float dy = new_posy - n_posy;
- p_offsetx = (n_posx != border_w);
- p_offsety = (n_posy != border_h);
- float r0 = 0.0f,
- g0 = 0.0f,
- b0 = 0.0f,
- r1 = 0.0f,
- g1 = 0.0f,
- b1 = 0.0f;
- new_index = n_posy * width + n_posx;
- r0 = *(rcopy + new_index);
- g0 = *(gcopy + new_index);
- b0 = *(bcopy + new_index);
- r1 = *(rcopy + new_index + p_offsetx);
- g1 = *(gcopy + new_index + p_offsetx);
- b1 = *(bcopy + new_index + p_offsetx);
- float r2 = 0.0f,
- g2 = 0.0f,
- b2 = 0.0f,
- r3 = 0.0f,
- g3 = 0.0f,
- b3 = 0.0f;
- new_index = (n_posy + p_offsety) * width + n_posx;
- r2 = *(rcopy + new_index);
- g2 = *(gcopy + new_index);
- b2 = *(bcopy + new_index);
- r3 = *(rcopy + new_index + p_offsetx);
- g3 = *(gcopy + new_index + p_offsetx);
- b3 = *(bcopy + new_index + p_offsetx);
- float r_val = 0.0f,
- g_val = 0.0f,
- b_val = 0.0f,
- fx1 = 0.0f,
- fx2 = 0.0f;
- fx1 = r0 + (r1 - r0) * dx;
- fx2 = r2 + (r3 - r2) * dx;
- r_val = fx1 + (fx2 - fx1) * dy;
- fx1 = g0 + (g1 - g0) * dx;
- fx2 = g2 + (g3 - g2) * dx;
- g_val = fx1 + (fx2 - fx1) * dy;
- fx1 = b0 + (b1 - b0) * dx;
- fx2 = b2 + (b3 - b2) * dx;
- b_val = fx1 + (fx2 - fx1) * dy; * (rdata + index) = *(rcopy + index) * 0.4f + r_val * 0.6f; * (gdata + index) = *(gcopy + index) * 0.4f + g_val * 0.6f; * (bdata + index) = *(bcopy + index) * 0.4f + b_val * 0.6f;
- }
- }
- free(rcopy);
- rcopy = NULL;
- free(gcopy);
- gcopy = NULL;
- free(bcopy);
- bcopy = NULL;
- }
颜料分散示例代码:
- void EdgeDarkening(float * rdata, float * gdata, float * bdata, float strength, int width, int height) {
- int step = width;
- int size = width * height;
- float * rcopy = (float * ) malloc(size * sizeof(float));
- float * gcopy = (float * ) malloc(size * sizeof(float));
- float * bcopy = (float * ) malloc(size * sizeof(float));
- memcpy(rcopy, rdata, size * sizeof(float));
- memcpy(gcopy, gdata, size * sizeof(float));
- memcpy(bcopy, bdata, size * sizeof(float));
- int index = 0;
- float * pSrcRData = NULL,
- *pSrcGData = NULL,
- *pSrcBData = NULL;
- float * pNewRData = NULL,
- *pNewGData = NULL,
- *pNewBData = NULL;
- float * pLeftData = NULL,
- *pRightData = NULL,
- *pUpData = NULL,
- *pDownData = NULL;
- for (int i = 1; i < height - 1; i++) {
- for (int j = 1; j < width - 1; j++) {
- index = i * width + j;
- // red
- pNewRData = rcopy + index;
- pLeftData = pNewRData - 1;
- pRightData = pNewRData + 1;
- pUpData = pNewRData - step;
- pDownData = pNewRData + step;
- float gradient_r = fabs( * pRightData - *pLeftData) + fabs( * pDownData - *pUpData);
- // green
- pNewGData = gcopy + index;
- pLeftData = pNewGData - 1;
- pRightData = pNewGData + 1;
- pUpData = pNewGData - step;
- pDownData = pNewGData + step;
- float gradient_g = fabs( * pRightData - *pLeftData) + fabs( * pDownData - *pUpData);
- // blue
- pNewBData = bcopy + index;
- pLeftData = pNewBData - 1;
- pRightData = pNewBData + 1;
- pUpData = pNewBData - step;
- pDownData = pNewBData + step;
- float gradient_b = fabs( * pRightData - *pLeftData) + fabs( * pDownData - *pUpData);
- // result
- float gradient = (gradient_r + gradient_g + gradient_b)
- /* / 1.0f*/
- ;
- pSrcRData = rdata + index;
- pSrcGData = gdata + index;
- pSrcBData = bdata + index; * pSrcRData = (float) CLAMP0255_XY(BousseauColorModel( * pSrcRData, gradient, strength), 1.0f); * pSrcGData = (float) CLAMP0255_XY(BousseauColorModel( * pSrcGData, gradient, strength), 1.0f); * pSrcBData = (float) CLAMP0255_XY(BousseauColorModel( * pSrcBData, gradient, strength), 1.0f);
- }
- }
- free(rcopy);
- rcopy = NULL;
- free(gcopy);
- gcopy = NULL;
- free(bcopy);
- bcopy = NULL;
- }
如果颜料分散模拟的好,感觉还是有水彩画那么点意思的,不过现在也懒得优化了,下面是一些效果图:
- void PigmentDispersion(float *rdata, float *gdata, float *bdata, float strength, int width, int height)
- {
- int size = width*height;
- float *noise_gaussian = (float *)malloc(size * sizeof(float));
- GaussianNoise(noise_gaussian, width, height);
- float *pSrcRData = rdata, *pSrcGData = gdata, *pSrcBData = bdata;
- for (int i = 0; i < size; i++, pSrcRData++, pSrcGData++, pSrcBData++)
- {
- *pSrcRData = (float)CLAMP0255_XY(BousseauColorModel(*pSrcRData, noise_gaussian[i], strength), 1.0f);
- *pSrcGData = (float)CLAMP0255_XY(BousseauColorModel(*pSrcGData, noise_gaussian[i], strength), 1.0f);
- *pSrcBData = (float)CLAMP0255_XY(BousseauColorModel(*pSrcBData, noise_gaussian[i], strength), 1.0f);
- }
- free(noise_gaussian);
- noise_gaussian = NULL;
- }
来源: http://www.bubuko.com/infodetail-1965625.html