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保证字节对齐。
(sxcong) |