示例#1
0
static GdkPixbuf *
colorize_pixbuf (GdkPixbuf *orig,
                 GdkRGBA   *new_color)
{
  GdkPixbuf *pixbuf;
  double intensity;
  int x, y;
  const guchar *src;
  guchar *dest;
  int orig_rowstride;
  int dest_rowstride;
  int width, height;
  gboolean has_alpha;
  const guchar *src_pixels;
  guchar *dest_pixels;

  pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (orig), gdk_pixbuf_get_has_alpha (orig),
			   gdk_pixbuf_get_bits_per_sample (orig),
			   gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));

  if (pixbuf == NULL)
    return NULL;

  orig_rowstride = gdk_pixbuf_get_rowstride (orig);
  dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  has_alpha = gdk_pixbuf_get_has_alpha (orig);
  src_pixels = gdk_pixbuf_get_pixels (orig);
  dest_pixels = gdk_pixbuf_get_pixels (pixbuf);

  for (y = 0; y < height; y++)
    {
      src = src_pixels + y * orig_rowstride;
      dest = dest_pixels + y * dest_rowstride;

      for (x = 0; x < width; x++)
        {
          double dr, dg, db;

          intensity = INTENSITY (src[0], src[1], src[2]) / 255.0;

          if (intensity <= 0.5)
            {
              /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */
              dr = new_color->red * intensity * 2.0;
              dg = new_color->green * intensity * 2.0;
              db = new_color->blue * intensity * 2.0;
            }
          else
            {
              /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */
              dr = new_color->red + (1.0 - new_color->red) * (intensity - 0.5) * 2.0;
              dg = new_color->green + (1.0 - new_color->green) * (intensity - 0.5) * 2.0;
              db = new_color->blue + (1.0 - new_color->blue) * (intensity - 0.5) * 2.0;
            }

          dest[0] = CLAMP_UCHAR (255 * dr);
          dest[1] = CLAMP_UCHAR (255 * dg);
          dest[2] = CLAMP_UCHAR (255 * db);

          if (has_alpha)
            {
              dest[3] = src[3];
              src += 4;
              dest += 4;
            }
          else
            {
              src += 3;
              dest += 3;
            }
        }
    }

  return pixbuf;
}
示例#2
0
/**
 * gdk_pixbuf_saturate_and_pixelate:
 * @src: source image
 * @dest: place to write modified version of @src
 * @saturation: saturation factor
 * @pixelate: whether to pixelate
 *
 * Modifies saturation and optionally pixelates @src, placing the result in
 * @dest. @src and @dest may be the same pixbuf with no ill effects.  If
 * @saturation is 1.0 then saturation is not changed. If it's less than 1.0,
 * saturation is reduced (the image turns toward grayscale); if greater than
 * 1.0, saturation is increased (the image gets more vivid colors). If @pixelate
 * is %TRUE, then pixels are faded in a checkerboard pattern to create a
 * pixelated image. @src and @dest must have the same image format, size, and
 * rowstride.
 * 
 **/
void
gdk_pixbuf_saturate_and_pixelate(const GdkPixbuf *src,
                                 GdkPixbuf *dest,
                                 gfloat saturation,
                                 gboolean pixelate)
{
        /* NOTE that src and dest MAY be the same pixbuf! */
  
        g_return_if_fail (GDK_IS_PIXBUF (src));
        g_return_if_fail (GDK_IS_PIXBUF (dest));
        g_return_if_fail (gdk_pixbuf_get_height (src) == gdk_pixbuf_get_height (dest));
        g_return_if_fail (gdk_pixbuf_get_width (src) == gdk_pixbuf_get_width (dest));
        g_return_if_fail (gdk_pixbuf_get_has_alpha (src) == gdk_pixbuf_get_has_alpha (dest));
        g_return_if_fail (gdk_pixbuf_get_colorspace (src) == gdk_pixbuf_get_colorspace (dest));
  
        if (saturation == 1.0 && !pixelate) {
                if (dest != src)
                        gdk_pixbuf_copy_area (src, 0, 0, 
                                              gdk_pixbuf_get_width (src),
                                              gdk_pixbuf_get_height (src),
                                              dest, 0, 0);
        } else {
                int i, j, t;
                int width, height, has_alpha, src_rowstride, dest_rowstride, bytes_per_pixel;
		const guchar *src_line;
		guchar *dest_line;
                const guchar *src_pixel;
		guchar *dest_pixel;
                guchar intensity;

                has_alpha = gdk_pixbuf_get_has_alpha (src);
		bytes_per_pixel = has_alpha ? 4 : 3;
                width = gdk_pixbuf_get_width (src);
                height = gdk_pixbuf_get_height (src);
                src_rowstride = gdk_pixbuf_get_rowstride (src);
                dest_rowstride = gdk_pixbuf_get_rowstride (dest);
                
                dest_line = gdk_pixbuf_get_pixels (dest);
                src_line = gdk_pixbuf_read_pixels (src);
		
#define DARK_FACTOR 0.7
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
#define CLAMP_UCHAR(v) (t = (v), CLAMP (t, 0, 255))
#define SATURATE(v) ((1.0 - saturation) * intensity + saturation * (v))

		for (i = 0 ; i < height ; i++) {
			src_pixel = src_line;
			src_line += src_rowstride;
			dest_pixel = dest_line;
			dest_line += dest_rowstride;

			for (j = 0 ; j < width ; j++) {
                                intensity = INTENSITY (src_pixel[0], src_pixel[1], src_pixel[2]);
                                if (pixelate && (i + j) % 2 == 0) {
                                        dest_pixel[0] = intensity / 2 + 127;
                                        dest_pixel[1] = intensity / 2 + 127;
                                        dest_pixel[2] = intensity / 2 + 127;
                                } else if (pixelate) {
                                        dest_pixel[0] = CLAMP_UCHAR ((SATURATE (src_pixel[0])) * DARK_FACTOR);
					dest_pixel[1] = CLAMP_UCHAR ((SATURATE (src_pixel[1])) * DARK_FACTOR);
                                        dest_pixel[2] = CLAMP_UCHAR ((SATURATE (src_pixel[2])) * DARK_FACTOR);
                                } else {
                                        dest_pixel[0] = CLAMP_UCHAR (SATURATE (src_pixel[0]));
                                        dest_pixel[1] = CLAMP_UCHAR (SATURATE (src_pixel[1]));
                                        dest_pixel[2] = CLAMP_UCHAR (SATURATE (src_pixel[2]));
                                }
				
                                if (has_alpha)
                                        dest_pixel[3] = src_pixel[3];

				src_pixel += bytes_per_pixel;
				dest_pixel += bytes_per_pixel;
			}
                }
        }
}