示例#1
0
文件: Image.cpp 项目: 540513310/fibjs
result_t Image::convert(int32_t color, AsyncEvent *ac)
{
    if (!m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    if (!ac)
        return CHECK_ERROR(CALL_E_NOSYNC);

    if (color != gd_base::_TRUECOLOR && color != gd_base::_PALETTE)
        return CHECK_ERROR(CALL_E_INVALIDARG);

    if (color == gd_base::_TRUECOLOR && !gdImageTrueColor(m_image))
    {
        setExtMemory(-1);
        gdImagePaletteToTrueColor(m_image);
        setExtMemory();
    }
    else if (color == gd_base::_PALETTE && gdImageTrueColor(m_image))
    {
        setExtMemory(-1);
        gdImageTrueColorToPalette(m_image, 1, 256);
        setExtMemory();
    }
    else
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    return 0;
}
示例#2
0
int main()
{
	gdImagePtr im, im2;
	int error = 0;

	im = gdImageCreateTrueColor(100, 100);

	if (im == NULL) {
		gdTestErrorMsg("gdImageCreateTruecolor failed\n");
		error = 1;
		goto exit;
	}
	gdImageColorTransparent(im, -1);
	gdImageTrueColorToPalette(im, 1, 3);
	gdImageColorTransparent(im, 9);
	im2 = gdImageScale(im, 1, 65535);
	if (im2 == NULL) {
		error = 1;
		goto freeim;
	} else {
		gdImageDestroy(im2);
	}

freeim:
	gdImageDestroy(im);
exit:
	return error;
}
示例#3
0
文件: testac.c 项目: mikekhusid/libgd
/* If palette is true, we convert from truecolor to palette at the end,
   to test gdImageTrueColorToPalette and see file size/
   quality tradeoffs. */
void
testDrawing (gdImagePtr im_in,
	     double scale, int blending, int palette, char *filename)
{
	gdImagePtr im_out;
	FILE *out;
	/* Create output image. */
	im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale),
					 (int) (gdImageSY (im_in) * scale));
	/*
	   Request alpha blending. This causes future
	   drawing operations to perform alpha channel blending
	   with the background, resulting in an opaque image.
	   Without this call, pixels in the foreground color are
	   copied literally, *including* the alpha channel value,
	   resulting in an output image which is potentially
	   not opaque. This flag can be set and cleared as often
	   as desired. */
	gdImageAlphaBlending (im_out, blending);

	/* Flood with light blue. */
	gdImageFill (im_out, (int) (gdImageSX (im_in) * scale / 2),
		     (int) (gdImageSY (im_in) * scale / 2),
		     gdTrueColor (192, 192, 255));
	/* Copy the source image. Alpha blending should result in
	   compositing against red. With blending turned off, the
	   browser or viewer will composite against its preferred
	   background, or, if it does not support an alpha channel,
	   we will see the original colors for the pixels that
	   ought to be transparent or semitransparent. */
	gdImageCopyResampled (im_out, im_in,
			      0, 0,
			      0, 0,
			      (int) (gdImageSX (im_in) * scale),
			      (int) (gdImageSY (im_in) * scale), gdImageSX (im_in),
			      gdImageSY (im_in));
	/* Write PNG */
	out = fopen (filename, "wb");

	/* If this image is the result of alpha channel blending,
	   it will not contain an interesting alpha channel itself.
	   Save a little file size by not saving the alpha channel.
	   Otherwise the file would typically be slightly larger. */
	gdImageSaveAlpha (im_out, !blending);

	/* If requested, convert from truecolor to palette. */
	if (palette) {
		/* Dithering, 256 colors. */
		gdImageTrueColorToPalette (im_out, 1, 256);
	}

	gdImagePng (im_out, out);
	fclose (out);

	gdImageDestroy (im_out);
}
示例#4
0
int main()
{
#ifdef HAVE_JPEG
	gdImagePtr im, im2;
	FILE *fp;
	char path[2048];

	fp=fopen("resampledbug.jpeg", "rb");
	if (!fp) {
		fprintf(stderr, "Can't load /home/pierre/IM3801.jpg\n");
		return 1;
	}

	im = gdImageCreateFromJpeg(fp);
	fclose(fp);
	if (!im) {
		fprintf(stderr, "Can't load TIFF image %s\n", path);
		return 1;
	}

	im2 = gdImageNeuQuant(im, 256, 3);

	if (im2) {
		gdImageSaveAlpha(im2, 1);
		save_png(im2, "a_nnquant.png");
		gdImageDestroy(im2);
	} else {
		printf("neu quant failed.\n");
	}

	gdImageTrueColorToPalette(im, 1, 256);

	gdImageSaveAlpha(im, 1);
	save_png(im, "a_jquant_dither.png");

	gdImageDestroy(im);
#else
	printf("JPEG support is required for this example. Please recompile GD with JPEG or change this example to use another format as input.");
	return 1;
#endif
	return 0;
}
static void make_thumb(void *conf)
{
	int colors = 0;
	int transparent = -1;
	ngx_image_conf_t *info = conf;
	info->dst_im = gdImageCreateTrueColor(info->width,info->height);
	colors = gdImageColorsTotal(info->src_im);
	transparent = gdImageGetTransparent(info->src_im);
	if (transparent == -1)
        {
		gdImageSaveAlpha(info->src_im,1);
		gdImageColorTransparent(info->src_im, -1);
		if(colors == 0)
		{
			gdImageAlphaBlending(info->dst_im,0);
			gdImageSaveAlpha(info->dst_im,1);
		}
		if(colors)
		{
			gdImageTrueColorToPalette(info->dst_im,1,256);
		}
    }
    if(info->w_margin == 1)
    {

		info->w_im = gdImageCreateTrueColor(info->width,info->height);
		gdImageFilledRectangle(info->w_im, 0, 0, info->width,info->height, gdImageColorAllocate(info->w_im, 255, 255, 255));
        info->dst_im = gdImageCreateTrueColor(info->max_width,info->max_height);
        gdImageFilledRectangle(info->dst_im, 0, 0, info->max_width,info->max_height, gdImageColorAllocate(info->dst_im, 255, 255, 255));
		gdImageCopyResampled(info->w_im, info->src_im, 0, 0, info->src_x, info->src_y,info->width, info->height, info->src_w,info->src_h);
		gdImageCopyResampled(info->dst_im, info->w_im, info->dst_x,info->dst_y, 0, 0,info->width, info->height, info->width, info->height);
        gdImageDestroy(info->w_im);
    }
    else
    {

        gdImageCopyResampled(info->dst_im,info->src_im,info->dst_x,info->dst_y,info->src_x,info->src_y,info->width,info->height,info->src_w,info->src_h);
    }
    gdImageDestroy(info->src_im);
}
示例#6
0
文件: nnquant.c 项目: cmb69/libgd
int main()
{
	gdImagePtr im, im2;
	FILE *fp;
	char path[2048];

	fp=fopen("resampledbug.jpeg", "rb");
	if (!fp) {
		fprintf(stderr, "Can't load /home/pierre/IM3801.jpg\n");
		return 1;
	}

	im = gdImageCreateFromJpeg(fp);
	fclose(fp);
	if (!im) {
		fprintf(stderr, "Can't load TIFF image %s\n", path);
		return 1;
	}

	im2 = gdImageNeuQuant(im, 256, 3);

	if (im2) {
		gdImageSaveAlpha(im2, 1);
		save_png(im2, "a_nnquant.png");
		gdImageDestroy(im2);
	} else {
		printf("neu quant failed.\n");
	}

	gdImageTrueColorToPalette(im, 1, 256);

	gdImageSaveAlpha(im, 1);
	save_png(im, "a_jquant_dither.png");

	gdImageDestroy(im);
	return 0;
}
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, ax, ay, size,
                                   colors, palette, transparent, sharpen,
                                   red, green, blue, t,
                                   offset_x, offset_y;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && ctx->angle == 0
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {

        resize = 0;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (ctx->angle) {
        src = dst;

        ax = (dx % 2 == 0) ? 1 : 0;
        ay = (dy % 2 == 0) ? 1 : 0;

        switch (ctx->angle) {

        case 90:
        case 270:
            dst = ngx_http_image_new(r, dy, dx, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            if (ctx->angle == 90) {
                ox = dy / 2 + ay;
                oy = dx / 2 - ax;

            } else {
                ox = dy / 2 - ay;
                oy = dx / 2 + ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);

            t = dx;
            dx = dy;
            dy = t;
            break;

        case 180:
            dst = ngx_http_image_new(r, dx, dy, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);
            break;
        }
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            offset_x = ngx_http_image_filter_get_value(r, conf->oxcv,
                                                       conf->offset_x);
            offset_y = ngx_http_image_filter_get_value(r, conf->oycv,
                                                       conf->offset_y);

            if (offset_x == NGX_HTTP_IMAGE_OFFSET_LEFT) {
                ox = 0;

            } else if (offset_x == NGX_HTTP_IMAGE_OFFSET_CENTER) {
                ox /= 2;
            }

            if (offset_y == NGX_HTTP_IMAGE_OFFSET_TOP) {
                oy = 0;

            } else if (offset_y == NGX_HTTP_IMAGE_OFFSET_CENTER) {
                oy /= 2;
            }

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
    if (sharpen > 0) {
        gdImageSharpen(dst, sharpen);
    }

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
示例#8
0
文件: gddemo.c 项目: aosm/graphviz
int
main (void)
{
#ifdef HAVE_LIBPNG
  /* Input and output files */
  FILE *in;
  FILE *out;

  /* Input and output images */
  gdImagePtr im_in = 0, im_out = 0;

  /* Brush image */
  gdImagePtr brush;

  /* Color indexes */
  int white;
  int blue;
  int red;
  int green;

  /* Points for polygon */
  gdPoint points[3];
  int i;

  /* Create output image, in true color. */
  im_out = gdImageCreateTrueColor (256 + 384, 384);
  /* 2.0.2: first color allocated would automatically be background in a 
     palette based image. Since this is a truecolor image, with an 
     automatic background of black, we must fill it explicitly. */
  white = gdImageColorAllocate (im_out, 255, 255, 255);
  gdImageFilledRectangle (im_out, 0, 0, gdImageSX (im_out),
			  gdImageSY (im_out), white);

  /* Set transparent color. */
  gdImageColorTransparent (im_out, white);

  /* Try to load demoin.png and paste part of it into the
     output image. */
  in = fopen ("demoin.png", "rb");
  if (!in)
    {
      fprintf (stderr, "Can't load source image; this demo\n");
      fprintf (stderr, "is much more impressive if demoin.png\n");
      fprintf (stderr, "is available.\n");
      im_in = 0;
    }
  else
    {
      int a;
      im_in = gdImageCreateFromPng (in);
      fclose (in);
      /* Now copy, and magnify as we do so */
      gdImageCopyResampled (im_out, im_in, 32, 32, 0, 0, 192, 192, 255, 255);
      /* Now display variously rotated space shuttles in a circle of our own */
      for (a = 0; (a < 360); a += 45)
	{
	  int cx = cos (a * .0174532925) * 128;
	  int cy = -sin (a * .0174532925) * 128;
	  gdImageCopyRotated (im_out, im_in,
			      256 + 192 + cx, 192 + cy,
			      0, 0, gdImageSX (im_in), gdImageSY (im_in), a);
	}
    }
  red = gdImageColorAllocate (im_out, 255, 0, 0);
  green = gdImageColorAllocate (im_out, 0, 255, 0);
  blue = gdImageColorAllocate (im_out, 0, 0, 255);
  /* Fat Rectangle */
  gdImageSetThickness (im_out, 4);
  gdImageLine (im_out, 16, 16, 240, 16, green);
  gdImageLine (im_out, 240, 16, 240, 240, green);
  gdImageLine (im_out, 240, 240, 16, 240, green);
  gdImageLine (im_out, 16, 240, 16, 16, green);
  gdImageSetThickness (im_out, 1);
  /* Circle */
  gdImageArc (im_out, 128, 128, 60, 20, 0, 720, blue);
  /* Arc */
  gdImageArc (im_out, 128, 128, 40, 40, 90, 270, blue);
  /* Flood fill: doesn't do much on a continuously
     variable tone jpeg original. */
  gdImageFill (im_out, 8, 8, blue);
  /* Polygon */
  points[0].x = 64;
  points[0].y = 0;
  points[1].x = 0;
  points[1].y = 128;
  points[2].x = 128;
  points[2].y = 128;
  gdImageFilledPolygon (im_out, points, 3, green);
  /* 2.0.12: Antialiased Polygon */
  gdImageSetAntiAliased (im_out, green);
  for (i = 0; (i < 3); i++)
    {
      points[i].x += 128;
    }
  gdImageFilledPolygon (im_out, points, 3, gdAntiAliased);
  /* Brush. A fairly wild example also involving a line style! */
  if (im_in)
    {
      int style[8];
      brush = gdImageCreateTrueColor (16, 16);
      gdImageCopyResized (brush, im_in,
			  0, 0, 0, 0,
			  gdImageSX (brush), gdImageSY (brush),
			  gdImageSX (im_in), gdImageSY (im_in));
      gdImageSetBrush (im_out, brush);
      /* With a style, so they won't overprint each other.
         Normally, they would, yielding a fat-brush effect. */
      style[0] = 0;
      style[1] = 0;
      style[2] = 0;
      style[3] = 0;
      style[4] = 0;
      style[5] = 0;
      style[6] = 0;
      style[7] = 1;
      gdImageSetStyle (im_out, style, 8);
      /* Draw the styled, brushed line */
      gdImageLine (im_out, 0, 255, 255, 0, gdStyledBrushed);
    }
  /* Text (non-truetype; see gdtestft for a freetype demo) */
  gdImageString (im_out, gdFontGiant, 32, 32, (unsigned char *) "hi", red);
  gdImageStringUp (im_out, gdFontSmall, 64, 64, (unsigned char *) "hi", red);
  /* Random antialiased lines; coordinates all over the image, 
    but the output will respect a small clipping rectangle */
  gdImageSetClip(im_out, 0, gdImageSY(im_out) - 100,
    100, gdImageSY(im_out)); 
  /* Fixed seed for reproducibility of results */
  srand(100);
  for (i = 0; (i < 100); i++) {
    int x1 = rand() % gdImageSX(im_out);
    int y1 = rand() % gdImageSY(im_out);
    int x2 = rand() % gdImageSX(im_out);
    int y2 = rand() % gdImageSY(im_out);
    gdImageSetAntiAliased(im_out, white);
    gdImageLine (im_out, x1, y1, x2, y2, gdAntiAliased);
  }
  /* Make output image interlaced (progressive, in the case of JPEG) */
  gdImageInterlace (im_out, 1);
  out = fopen ("demoout.png", "wb");
  /* Write PNG */
  gdImagePng (im_out, out);
  fclose (out);
  /* 2.0.12: also write a paletteized version */
  out = fopen ("demooutp.png", "wb");
  gdImageTrueColorToPalette (im_out, 0, 256);
  gdImagePng (im_out, out);
  fclose (out);
  gdImageDestroy (im_out);
  if (im_in)
    {
      gdImageDestroy (im_in);
    }
#else
  fprintf (stderr, "No PNG library support.\n");
#endif /* HAVE_LIBPNG */
  return 0;
}
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, size,
                                   colors, palette, transparent,
                                   red, green, blue;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((ngx_uint_t) (dx * 100 / dy)
            < ctx->max_width * 100 / ctx->max_height)
        {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            ox /= 2;
            oy /= 2;

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
static VALUE fastimage_native_resize(
        VALUE self,
        VALUE rb_in, VALUE rb_out,
        VALUE rb_w, VALUE rb_h,
        VALUE rb_image_type,
        VALUE rb_jpeg_quality,
        VALUE rb_orientation
       ) {
  char *filename_in  = StringValuePtr(rb_in);
  char *filename_out = StringValuePtr(rb_out);
  int w              = NUM2INT(rb_w);
  int h              = NUM2INT(rb_h);
  int image_type     = NUM2INT(rb_image_type);
  int jpeg_quality   = NUM2INT(rb_jpeg_quality);
  int orientation    = NUM2INT(rb_orientation);


  gdImagePtr im_in, im_out;
  FILE *in, *out;
  int trans = 0, x = 0, y = 0, f = 0;

  in = fopen(filename_in, "rb");
  if (!in) return Qnil;

  switch(image_type) {
    case 0: im_in = gdImageCreateFromJpeg(in);
            break;
    case 1: im_in = gdImageCreateFromPng(in);
            break;
    case 2: im_in = gdImageCreateFromGif(in);
            trans = gdImageGetTransparent(im_in);
            /* find a transparent pixel, then turn off transparency
               so that it copies correctly */
            if (trans >= 0) {
              for (x=0; x<gdImageSX(im_in); x++) {
                for (y=0; y<gdImageSY(im_in); y++) {
                  if (gdImageGetPixel(im_in, x, y) == trans) {
                    f = 1;
                    break;
                  }
                }
                if (f) break;
              }
              gdImageColorTransparent(im_in, -1);
              if (!f) trans = -1;  /* no transparent pixel found */
            }
            break;
  }

  if (!im_in) {
    fclose(in);
    return Qnil;
  }



  /*  Handle orientation */
  if (orientation == 5 || orientation == 6) {
    im_in = gdImageRotateInterpolated(im_in, 270.0, 0);
  }
  if (orientation == 7 || orientation == 8) {
    im_in = gdImageRotateInterpolated(im_in, 90.0, 0);
  }
  if (!im_in) {
    fclose(in);
    return Qnil;
  }

  if (orientation == 2 || orientation == 5 || orientation == 7) {
    gdImageFlipHorizontal(im_in);
  }
  if (orientation == 3) {
      gdImageFlipBoth(im_in);
  }
  if (orientation == 4) {
    gdImageFlipVertical(im_in);
  }



  /* Compute target size */
  if (w == 0 || h == 0) {
    int originalWidth  = gdImageSX(im_in);
    int originalHeight = gdImageSY(im_in);
    if (h != 0) {
      w = (int)(h * originalWidth / originalHeight);
    } else if (w != 0) {
      h = (int)(w * originalHeight / originalWidth);
    } else {
      w = originalWidth;
      h = originalHeight;
    }
  }



  im_out = gdImageCreateTrueColor(w, h);  /* must be truecolor */
  if (im_out) {
    if (image_type == 1) {
      gdImageAlphaBlending(im_out, 0);  /* handle transparency correctly */
      gdImageSaveAlpha(im_out, 1);
    }
    fclose(in);
  } else {
    fclose(in);
    return Qnil;
  }

  /* Now copy the original */
  gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0,
    gdImageSX(im_out), gdImageSY(im_out),
    gdImageSX(im_in), gdImageSY(im_in));

  out = fopen(filename_out, "wb");
  if (out) {
    switch(image_type) {
      case 0: gdImageJpeg(im_out, out, jpeg_quality);
              break;
      case 1: gdImagePng(im_out, out);
              break;
      case 2: gdImageTrueColorToPalette(im_out, 0, 256);
              if (trans >= 0) {
                trans = gdImageGetPixel(im_out, x, y);  /* get the color index of our transparent pixel */
                gdImageColorTransparent(im_out, trans); /* may not always work as hoped */
              }
              gdImageGif(im_out, out);
              break;
    }
    fclose(out);
  }
  gdImageDestroy(im_in);
  gdImageDestroy(im_out);
  return Qnil;
}
示例#11
0
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, ax, ay, size,
                                   colors, palette, transparent, sharpen,
                                   red, green, blue, t;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && ctx->angle == 0
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {

        resize = 0;

    } else if (conf->filter == NGX_HTTP_IMAGE_WATERMARK) {

        resize = 0;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (ctx->angle) {
        src = dst;

        ax = (dx % 2 == 0) ? 1 : 0;
        ay = (dy % 2 == 0) ? 1 : 0;

        switch (ctx->angle) {

        case 90:
        case 270:
            dst = ngx_http_image_new(r, dy, dx, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            if (ctx->angle == 90) {
                ox = dy / 2 + ay;
                oy = dx / 2 - ax;

            } else {
                ox = dy / 2 - ay;
                oy = dx / 2 + ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);

            t = dx;
            dx = dy;
            dy = t;
            break;

        case 180:
            dst = ngx_http_image_new(r, dx, dy, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);
            break;
        }
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            ox /= 2;
            oy /= 2;

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    if (conf->filter == NGX_HTTP_IMAGE_WATERMARK && conf->watermark.data) {
        FILE *watermark_file = fopen((const char *)conf->watermark.data, "r");

        if (watermark_file) {
            gdImagePtr watermark, watermark_mix;
            ngx_int_t wdx = 0, wdy = 0;

            watermark = gdImageCreateFromPng(watermark_file);

            if(watermark != NULL) {
                watermark_mix = gdImageCreateTrueColor(watermark->sx, watermark->sy);

                if (ngx_strcmp(conf->watermark_position.data, "bottom-right") == 0) {
                    wdx = dx - watermark->sx - 10;
                    wdy = dy - watermark->sy - 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "top-left") == 0) {
                    wdx = wdy = 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "top-right") == 0) {
                    wdx = dx - watermark->sx - 10;
                    wdy = 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "bottom-left") == 0) {
                    wdx = 10;
                    wdy = dy - watermark->sy - 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "center") == 0) {
                    wdx = dx / 2 - watermark->sx / 2;
                    wdy = dy / 2 - watermark->sy / 2;
                }

                gdImageCopy(watermark_mix, dst, 0, 0, wdx, wdy, watermark->sx, watermark->sy);
                gdImageCopy(watermark_mix, watermark, 0, 0, 0, 0, watermark->sx, watermark->sy);
                gdImageCopyMerge(dst, watermark_mix, wdx, wdy, 0, 0, watermark->sx, watermark->sy, 75);
                gdFree(watermark);
                gdFree(watermark_mix);

            } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' is not PNG", conf->watermark.data);}

        } else {

            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' not found", conf->watermark.data);
        }
    }

    sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
    if (sharpen > 0) {
        gdImageSharpen(dst, sharpen);
    }

    gdImageInterlace(dst, (int) conf->interlace);

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
static VALUE fir_resize_image(VALUE self, VALUE raw_filename_in, VALUE raw_filename_out, VALUE raw_width, VALUE raw_height, VALUE raw_image_type, VALUE raw_jpeg_quality) {
  gdImagePtr im_in, im_out;
  FILE *in, *out;
  char *filename_in; char *filename_out;
  int w; int h; int image_type; int jpeg_quality;
  int trans = 0, x = 0, y = 0, f = 0;

  filename_in = RSTRING_PTR(raw_filename_in);
  filename_out = RSTRING_PTR(raw_filename_out);
  w = NUM2INT(raw_width);
  h = NUM2INT(raw_height);
  image_type = NUM2INT(raw_image_type);
  jpeg_quality = NUM2INT(raw_jpeg_quality);

  in = fopen(filename_in, "rb");
  if (!in) return Qnil;

  switch(image_type) {
    case 0: im_in = gdImageCreateFromJpeg(in);
            break;
    case 1: im_in = gdImageCreateFromPng(in);
            break;
    case 2: im_in = gdImageCreateFromGif(in);
            trans = gdImageGetTransparent(im_in);
            /* find a transparent pixel, then turn off transparency
               so that it copies correctly */
            if (trans >= 0) {
              for (x=0; x<gdImageSX(im_in); x++) {
                for (y=0; y<gdImageSY(im_in); y++) {
                  if (gdImageGetPixel(im_in, x, y) == trans) {
                    f = 1;
                    break;
                  }
                }
                if (f) break;
              }
              gdImageColorTransparent(im_in, -1);
              if (!f) trans = -1;  /* no transparent pixel found */
            }
            break;
    default: return Qnil;
  }

  if (w == 0 || h == 0) {
    int originalWidth  = gdImageSX(im_in);
    int originalHeight = gdImageSY(im_in);
    if (w == 0) {
      w = (int)(h * originalWidth / originalHeight);
    } else {
      h = (int)(w * originalHeight / originalWidth);
    }
  }

  im_out = gdImageCreateTrueColor(w, h);  /* must be truecolor */

  if (image_type == 1) {
    gdImageAlphaBlending(im_out, 0);  /* handle transparency correctly */
    gdImageSaveAlpha(im_out, 1);
  }
  
  fclose(in);
  
  /* Now copy the original */
  gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0,
    gdImageSX(im_out), gdImageSY(im_out),
    gdImageSX(im_in), gdImageSY(im_in));

  out = fopen(filename_out, "wb");
  if (out) {
    switch(image_type) {
      case 0: gdImageJpeg(im_out, out, jpeg_quality);
              break;
      case 1: gdImagePng(im_out, out);
              break;
      case 2: gdImageTrueColorToPalette(im_out, 0, 256);
              if (trans >= 0) {
                trans = gdImageGetPixel(im_out, x, y);  /* get the color index of our transparent pixel */
                gdImageColorTransparent(im_out, trans); /* may not always work as hoped */
              }
              gdImageGif(im_out, out);
              break;
    }
    fclose(out);
  }
  gdImageDestroy(im_in);
  gdImageDestroy(im_out);
  return Qnil;
}
ngx_int_t ngx_http_small_light_gd_process(ngx_http_request_t *r, ngx_http_small_light_ctx_t *ctx)
{
    ngx_http_small_light_gd_ctx_t     *ictx;
    ngx_http_small_light_image_size_t  sz;
    gdImagePtr                         src, dst, canvas;
    ngx_int_t                          colors, transparent, palette, red, green, blue;
    ngx_int_t                          ax, ay, ox, oy, type;
    int                                iw, ih, radius, ccolor, bcolor;
    char                              *sharpen, *of;
    u_char                            *out;
    int                                size;
    double                             q;

    ictx = (ngx_http_small_light_gd_ctx_t *)ctx->ictx;
    src  = ngx_http_small_light_gd_src(ictx);
    if (src == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to get image source %s:%d",
                      __FUNCTION__,
                      __LINE__);
        return NGX_ERROR;
    }

    /* adjust image size */
    iw = gdImageSX(src);
    ih = gdImageSY(src);
    ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih);

    colors      = gdImageColorsTotal(src);
    palette     = 0;
    transparent = -1;
    red         = 0;
    green       = 0;
    blue        = 0;

    if (colors) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red     = gdImageRed(src,   transparent);
            green   = gdImageGreen(src, transparent);
            blue    = gdImageBlue(src,  transparent);
        }
    }

    gdImageColorTransparent(src, -1);

    /* rotate. */
    if (sz.angle) {
        dst = src;
        ax  = (iw % 2 == 0) ? 1 : 0;
        ay  = (ih % 2 == 0) ? 1 : 0;
        switch (sz.angle) {
        case 90:
        case 270:
            dst = ngx_http_small_light_gd_new(ih, iw, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NGX_ERROR;
            }

            if (sz.angle == 90) {
                ox = ih / 2 - ay;
                oy = iw / 2 + ax;
            } else {
                ox = ih / 2 + ay;
                oy = iw / 2 - ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               iw, ih, -sz.angle);
            gdImageDestroy(src);

            break;
        case 180:
            dst = ngx_http_small_light_gd_new(iw, ih, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NGX_ERROR;
            }
            gdImageCopyRotated(dst, src, iw / 2 - ax, ih / 2 - ay, 0, 0,
                               iw + ax, ih + ay, sz.angle);
            gdImageDestroy(src);
            break;
        default:
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "image not rotated. 'angle'(%ui) must be 90 or 180 or 270. %s:%d",
                          sz.angle,
                          __FUNCTION__,
                          __LINE__);
            break;
        }
        src = dst;
    }

    /* calc size. */
    iw = gdImageSX(src);
    ih = gdImageSY(src);
    ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih);

    /* pass through. */
    if (sz.pt_flg != 0) {
        gdImageDestroy(src);
        ctx->of = ctx->inf;
        return NGX_OK;
    }

    /* crop, scale. */
    if (sz.scale_flg != 0) {
        dst = ngx_http_small_light_gd_new(sz.dw, sz.dh, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NGX_ERROR;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, sz.sx, sz.sy, sz.dw, sz.dh, sz.sw, sz.sh);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);
    } else {
        dst = src;
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    /* effects. */
    sharpen = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "sharpen");
    if (sharpen != NULL) {
        radius = ngx_http_small_light_parse_int(sharpen);
        if (radius > 0) {
            gdImageSharpen(dst, radius);
        }
    }

    /* interlace */
    gdImageInterlace(dst, 1);

    /* create canvas then draw image to the canvas. */
    if (sz.cw > 0.0 && sz.ch > 0.0) {
        canvas = gdImageCreateTrueColor(sz.cw, sz.ch);
        if (canvas == NULL) {
            gdImageDestroy(dst);
            return NGX_ERROR;
        }
        ccolor = gdImageColorAllocateAlpha(canvas, sz.cc.r, sz.cc.g, sz.cc.b, sz.cc.a);
        gdImageFilledRectangle(canvas, 0, 0, sz.cw, sz.ch, ccolor);
        gdImageCopy(canvas, dst, sz.dx, sz.dy, 0, 0, sz.dw, sz.dh);
        gdImageDestroy(dst);
        dst = canvas;
    }

    /* border. */
    if (sz.bw > 0.0 || sz.bh > 0.0) {
        bcolor = gdImageColorAllocateAlpha(dst, sz.bc.r, sz.bc.g, sz.bc.b, sz.bc.a);
        if (sz.cw > 0.0 && sz.ch > 0.0) {
            gdImageFilledRectangle(dst, 0, 0, sz.cw, sz.bh, bcolor);
            gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.ch, bcolor);
            gdImageFilledRectangle(dst, 0, sz.ch - sz.bh, sz.cw - 1, sz.ch - 1, bcolor);
            gdImageFilledRectangle(dst, sz.cw - sz.bw, 0, sz.cw - 1, sz.ch - 1, bcolor);
        } else {
            gdImageFilledRectangle(dst, 0, 0, sz.dw, sz.bh, bcolor);
            gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.dh, bcolor);
            gdImageFilledRectangle(dst, 0, sz.dh - sz.bh, sz.dw - 1, sz.dh - 1, bcolor);
            gdImageFilledRectangle(dst, sz.dw - sz.bw, 0, sz.dw - 1, sz.dh - 1, bcolor);
        }
    }

    of = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "of");
    if (ngx_strlen(of) > 0) {
        type = ngx_http_small_light_type(of);
        if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_NONE) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "of is invalid(%s) %s:%d",
                          of,
                          __FUNCTION__,
                          __LINE__);
        } else if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_WEBP) {
#ifdef NGX_HTTP_SMALL_LIGHT_GD_WEBP_ENABLED
            ictx->type = type;
#else
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "WebP is not supported %s:%d",
                          __FUNCTION__,
                          __LINE__);
#endif
        } else {
            ictx->type = type;
        }
    }

    ctx->of = ngx_http_small_light_image_types[ictx->type - 1];

    q = ngx_http_small_light_parse_double(NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "q"));
    if (q == 0) {
        q = 100;
    }
    out = ngx_http_small_light_gd_out(dst, ictx->type, (int *)&size, q);
    gdImageDestroy(dst);

    if (out == NULL) {
        return NGX_ERROR;
    }

    /* get small_lighted image as binary. */
    ctx->content        = out;
    ctx->content_length = size;

    ngx_pfree(r->pool, ctx->content_orig);

    ictx->complete = 1;

    return NGX_OK;
}
示例#14
0
static void gd_end_graph(void)
{
    if (!im || external_surface)
        return;

    /*
     * Windows will do \n -> \r\n  translations on stdout unless told otherwise.
     */
#ifdef HAVE_SETMODE
#ifdef O_BINARY
    setmode(fileno(Output_file), O_BINARY);
#endif
#endif

    /* Only save the alpha channel in outputs that support it if
       the base color was transparent.   Otherwise everything
       was blended so there is no useful alpha info */
    if (im->trueColor) {
        if (is_format_truecolor_capable(Output_lang))
            gdImageSaveAlpha(im, TRUE);
        else
            gdImageTrueColorToPalette(im, 0, 256);
    }
    if (Output_lang == GD) {
        gdImageGd(im, Output_file);
#ifdef HAVE_LIBZ
    } else if (Output_lang == GD2) {
#define GD2_CHUNKSIZE 128
#define GD2_RAW 1
#define GD2_COMPRESSED 2
        gdImageGd2(im, Output_file, GD2_CHUNKSIZE, GD2_COMPRESSED);
#endif
#ifdef HAVE_GD_GIF
    } else if (Output_lang == GIF) {
        gdImageGif(im, Output_file);
#endif
#ifdef HAVE_GD_JPEG
    } else if (Output_lang == JPEG) {
        /*
         * Write IM to OUTFILE as a JFIF-formatted JPEG image, using
         * quality JPEG_QUALITY.  If JPEG_QUALITY is in the range
         * 0-100, increasing values represent higher quality but
         * also larger image size.  If JPEG_QUALITY is negative, the
         * IJG JPEG library's default quality is used (which should
         * be near optimal for many applications).  See the IJG JPEG
         * library documentation for more details.
         */
#define JPEG_QUALITY -1
        gdImageJpeg(im, Output_file, JPEG_QUALITY);
#endif
#ifdef HAVE_GD_PNG
    } else if (Output_lang == PNG) {
        gdImagePng(im, Output_file);
#endif
    } else if (Output_lang == WBMP) {
        /* Use black for the foreground color for the B&W wbmp image. */
        gdImageWBMP(im, black, Output_file);
#ifdef HAVE_GD_XPM
    } else if (Output_lang == XBM) {
        gdImageXbm(im, Output_file);
#endif
    }
    gd_freeusershapes();
    gdImageDestroy(im);
#ifdef MYTRACE
    fprintf(stderr, "gd_end_graph_to_file\n");
#endif
}
示例#15
0
int
main (int argc, char *argv[])
{
	gdImagePtr im;
	int blue;
	int blueAlpha;
	int white;
	int brect[8];
	int x, y, sx, sy;
	char *err;
	FILE *out;
#ifdef JISX0208
	char *s = "Hello. ‚±‚ñ‚É‚¿‚Í Qyjpqg,";	/* String to draw. */
#else
	char *s = "Hello. �ん��� Qyjpqg,";	/* String to draw. */
#endif

	double sz = 40.;

#if 0
	double angle = 0.;
#else
	double angle = DEG2RAD (90);
#endif
	char *f;
	if (argc == 2) {
		f = argv[1];
	} else {
		/* 2.02: usage message. Defaulting to Times wasn't working well for the
		   many people with no /usr/share/fonts/truetype. */
		fprintf(stderr, "Usage: gdtestft fontfilename\n"
			 "If fontfilename is not a full or relative path, GDFONTPATH is searched for\n"
		         "it. If GDFONTPATH is not set, /usr/share/fonts/truetype is searched.\n");
		return 1;
	}
	/* obtain brect so that we can size the image */
	err =
	    gdImageStringFT ((gdImagePtr) NULL, &brect[0], 0, f, sz, angle, 0, 0, s);
	if (err) {
		fprintf(stderr, "%s\n", err);
		return 1;
	}

	/* create an image just big enough for the string (x3) */
	sx = MAXX (brect) - MINX (brect) + 6;
	sy = MAXY (brect) - MINY (brect) + 6;
#if 0
	/* Would be palette color 8-bit (which of course is still allowed,
	   but not impressive when used with a JPEG background and antialiasing
	   and alpha channel and so on!) */
	im = gdImageCreate (sx * 3, sy);
#else
	/* gd 2.0: true color images can use freetype too,
	   and they can do antialiasing against arbitrary
	   complex backgrounds. */
	im = gdImageCreateTrueColor (sx * 3, sy);
#endif
	/* Background color. gd 2.0: fill the image with it; truecolor
	   images have a black background otherwise. */
	white = gdImageColorResolve (im, 255, 255, 255);
	/* Load a pretty background and resample it to cover the entire image */
	{
		FILE *in = fopen ("eleanor.jpg", "rb");
		gdImagePtr imb = NULL;
		if (in) {
#ifdef HAVE_LIBJPEG
			imb = gdImageCreateFromJpeg (in);
#else
			fprintf(stderr, "No JPEG library support.\n");
#endif
			fclose(in);

			if (!imb) {
				fprintf(stderr, "gdImageCreateFromJpeg failed\n");
				return 1;
			}
			if (!im->trueColor) {
				/* If destination is not truecolor, convert the JPEG to a
				   reasonably high-quality palette version. This is not as good
				   as creating a truecolor output file, of course. Leave many
				   colors for text smoothing. */
#if 1
				gdImageTrueColorToPalette (imb, 0, 128);
#endif
			}
			/* Resample background image to cover new image exactly */
			gdImageCopyResampled (im, imb, 0, 0, 0, 0, sx * 3, sy,
			                      gdImageSX (imb), gdImageSY (imb));
		} else {
			/* Can't get background, so paint a simple one */
			/* Truecolor images start out black, so paint it white */
			gdImageFilledRectangle (im, 0, 0, sx * 3, sy, white);
		}
	}
	/* TBB 2.0.2: only black was working, and I didn't know it because
	   the test program used black. Funny, huh? Let's do a more interesting
	   color this time.  */
	blue = gdImageColorResolve (im, 128, 192, 255);
	/* Almost-transparent blue (alpha blending), with antialiasing */
	blueAlpha = gdImageColorResolveAlpha (im, 128, 192, 255, gdAlphaMax / 2);
	/* render the string, offset origin to center string */
	x = 0 - MINX (brect) + 3;
	y = 0 - MINY (brect) + 3;

	/* With antialiasing (positive color value) */
	err = gdImageStringFT (im, NULL, blue, f, sz, angle, x, y, s);
	if (err) {
		fprintf(stderr, "%s\n", err);
		return 1;
	}
	/* Without antialiasing (negative color value) */
	err = gdImageStringFT (im, NULL, -blue, f, sz, angle, sx + x, y, s);
	if (err) {
		fprintf(stderr, "%s\n", err);
		return 1;
	}
	/* With antialiasing, and 50% alpha blending (truecolor only) */
	err = gdImageStringFT (im, NULL, blueAlpha, f, sz, angle, sx * 2 + x, y, s);
	if (err) {
		fprintf(stderr, "%s\n", err);
		return 1;
	}
	/* TBB: Write img to test/fttest.jpg or test/fttest.png */
	if (im->trueColor) {
#ifdef HAVE_LIBJPEG
		out = fopen ("test/fttest.jpg", "wb");
		if (!out) {
			fprintf(stderr, "Can't create test/fttest.jpg\n");
			exit (1);
		}
		/* Fairly high JPEG quality setting */
		gdImageJpeg (im, out, 90);
		fclose (out);
		fprintf(stderr, "Test image written to test/fttest.jpg\n");
#else
		fprintf(stderr, "Test image not written; No JPEG library support.\n");
#endif
	} else {
#ifdef HAVE_LIBPNG
		out = fopen ("test/fttest.png", "wb");
		if (!out) {
			fprintf(stderr, "Can't create test/fttest.png\n");
			exit (1);
		}
		/* 2.0.10: correct ifdef, thanks to Gabriele Verzeletti */
		gdImagePng (im, out);
		fclose (out);
		fprintf(stderr, "Test image written to test/fttest.png\n");
#else
		fprintf(stderr, "Test image not written; No PNG library support.\n");
#endif
	}
	/* Destroy it */
	gdImageDestroy (im);

	return 0;
}