织梦CMS - 轻松建站从此开始!

罗索

GIMP的去红眼(remove_redeye)源码分析及提取改写

落鹤生 发布于 2013-05-07 22:06 点击:次 
主要功能在redeye_inner_loop这个函数里,这个函数里面要改两处:1 把gint之类改成int;2 原程序是按r,g,b,a来处理的,实际要反过来
TAG:

GIMP源程序:

  1. static void 
  2. remove_redeye (GimpDrawable *drawable) 
  3.   GimpPixelRgn  src_rgn; 
  4.   GimpPixelRgn  dest_rgn; 
  5.   gint          progress, max_progress; 
  6.   gboolean      has_alpha; 
  7.   gint          x, y; 
  8.   gint          width, height; 
  9.   gint          i; 
  10.   gpointer      pr; 
  11.  
  12.  
  13.   if (! gimp_drawable_mask_intersect (drawable->drawable_id, 
  14.                                       &x, &y, &width, &height)) 
  15.     return
  16.  
  17.  
  18.   gimp_progress_init (_("Removing red eye")); 
  19.  
  20.  
  21.   has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); 
  22.  
  23.  
  24.   progress = 0; 
  25.   max_progress = width * height; 
  26.  
  27.  
  28.   gimp_pixel_rgn_init (&src_rgn, drawable, 
  29.                        x, y, width, height, FALSE, FALSE); 
  30.   gimp_pixel_rgn_init (&dest_rgn, drawable, 
  31.                        x, y, width, height, TRUE, TRUE); 
  32.  
  33.  
  34.   for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), i = 0; 
  35.        pr != NULL; 
  36.        pr = gimp_pixel_rgns_process (pr), i++) 
  37.     { 
  38.       redeye_inner_loop (src_rgn.data, dest_rgn.data, src_rgn.w, src_rgn.h, 
  39.                          src_rgn.bpp, has_alpha, src_rgn.rowstride); 
  40.  
  41.  
  42.       progress += src_rgn.w * src_rgn.h; 
  43.  
  44.  
  45.       if (i % 16 == 0) 
  46.         gimp_progress_update ((gdouble) progress / (gdouble) max_progress); 
  47.     } 
  48.  
  49.  
  50.   gimp_progress_update (1.0); 
  51.   gimp_drawable_flush (drawable); 
  52.   gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); 
  53.   gimp_drawable_update (drawable->drawable_id, x, y, width, height); 

主要功能在redeye_inner_loop这个函数里,这个函数里面要改两处:
1 把gint之类改成int
2 原程序是按r,g,b,a来处理的,实际要反过来,也就是说,

const gint red   = 0;
const gint green = 1;
const gint blue  = 2;
const gint alpha = 3;
倒序就可以了。程序里实际操作的图都是24位真彩,没有用到a,所以改成了:
const int red   = 2;
 const int green = 1;
 const int blue  = 0;
 const int alpha = 3;//没有用到

主要改造remove_redeye 这个函数。说改造,其实就是按范围取值计算而已。
简单改写之写:

  1. #define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) 
  2.  
  3. void remove_redeye() 
  4.  
  5.  if (!m_image.isValid()) 
  6.  return
  7.  //准备数据 
  8.   int bytes = m_image.getBitsPerPixel()/8; 
  9.    
  10.   bool has_alpha = m_image.isTransparent(); 
  11.  
  12.   fipWinImage image2 = m_image; 
  13.   int x = 0; 
  14.   int y = 0; 
  15.   int width = m_image.getWidth(); 
  16.   int height = m_image.getHeight(); 
  17.   int size = width*height*3; 
  18.   size = WIDTHBYTES(m_image.getBitsPerPixel()*width)*height; 
  19.  
  20.   BITMAPINFO* info = m_image.getInfo(); 
  21.   int rowstride = WIDTHBYTES(m_image.getBitsPerPixel()*width); 
  22.     
  23.   BYTE *src_ptr  = m_image.accessPixels(); 
  24.   BYTE *dest_ptr = new BYTE[size]; 
  25.   BYTE* dest_line = dest_ptr; 
  26.  
  27.  
  28.   redeye_inner_loop(src_ptr, dest_ptr, width, height, bytes, has_alpha, rowstride); 
  29.  
  30.  
  31.   char* szFile = "out.bmp"
  32.   g_fSaveDataToBitmap(&(info->bmiHeader), szFile, dest_ptr, m_image.getImageSize()); 
  33.   m_imageDest.load(szFile); 
  34.   if (!m_imageDest.isValid()) 
  35.   { 
  36.  AfxMessageBox("处理失败!"); 
  37.   } 
  38.    
  39.   delete[] dest_ptr; 

程序使用freeimage读出源图,处理完保存成bmp。注意,一定要用WIDTHBYTES保证字节对齐。

(sxcong)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201305/16618.html]
本文出处:ChinaUnix 作者:sxcong 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容