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

GIMP源程序:
static void
remove_redeye (GimpDrawable *drawable)
{
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  dest_rgn;
  gint          progress, max_progress;
  gboolean      has_alpha;
  gint          x, y;
  gint          width, height;
  gint          i;
  gpointer      pr;


  if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                      &x, &y, &width, &height))
    return;


  gimp_progress_init (_("Removing red eye"));


  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);


  progress = 0;
  max_progress = width * height;


  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x, y, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x, y, width, height, TRUE, TRUE);


  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), i = 0;
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr), i++)
    {
      redeye_inner_loop (src_rgn.data, dest_rgn.data, src_rgn.w, src_rgn.h,
                         src_rgn.bpp, has_alpha, src_rgn.rowstride);


      progress += src_rgn.w * src_rgn.h;


      if (i % 16 == 0)
        gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
    }


  gimp_progress_update (1.0);
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  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 这个函数。说改造,其实就是按范围取值计算而已。
简单改写之写:

#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8)

void remove_redeye()
{

 if (!m_image.isValid())
 return;
 //准备数据
  int bytes = m_image.getBitsPerPixel()/8;
  
  bool has_alpha = m_image.isTransparent();

  fipWinImage image2 = m_image;
  int x = 0;
  int y = 0;
  int width = m_image.getWidth();
  int height = m_image.getHeight();
  int size = width*height*3;
  size = WIDTHBYTES(m_image.getBitsPerPixel()*width)*height;

  BITMAPINFO* info = m_image.getInfo();
  int rowstride = WIDTHBYTES(m_image.getBitsPerPixel()*width);
   
  BYTE *src_ptr  = m_image.accessPixels();
  BYTE *dest_ptr = new BYTE[size];
  BYTE* dest_line = dest_ptr;


  redeye_inner_loop(src_ptr, dest_ptr, width, height, bytes, has_alpha, rowstride);


  char* szFile = "out.bmp";
  g_fSaveDataToBitmap(&(info->bmiHeader), szFile, dest_ptr, m_image.getImageSize());
  m_imageDest.load(szFile);
  if (!m_imageDest.isValid())
  {
 AfxMessageBox("处理失败!");
  }
  
  delete[] dest_ptr;
}

程序使用freeimage读出源图,处理完保存成bmp。注意,一定要用WIDTHBYTES保证字节对齐。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值