watermark patch

Trurl nginx-forum at nginx.us
Wed Feb 6 11:17:31 UTC 2013


откопал старый патч watermark patch by Vadym Zakovinko
причесал, добавил проверок, убрал memory leaking (надеюсь), переделал с JPG
на PNG, добавил полноценную работу с альфаканалом. Работает с версией
1.2.6.

пример использования
        location /images/ {
                image_filter_buffer 10M;
                image_filter_watermark "/srv/www/htdocs/images/swtor.png";
                image_filter_watermark_position top-right; #
top-left|top-right|bottom-right|bottom-left
                image_filter watermark;
                expires -1;
        }
 
сам патч:

--- src/http/modules/ngx_http_image_filter_module.c
+++ src/http/modules/ngx_http_image_filter_module.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) Igor Sysoev
  * Copyright (C) Nginx, Inc.
+ * watermark patch: Vadym Zakovinko <vp.zakovinko at gmail.com> updated by
Trurl McByte <trurl at mcbyte.net>
  */


@@ -18,6 +19,7 @@
 #define NGX_HTTP_IMAGE_RESIZE    3
 #define NGX_HTTP_IMAGE_CROP      4
 #define NGX_HTTP_IMAGE_ROTATE    5
+#define NGX_HTTP_IMAGE_WATERMARK 6


 #define NGX_HTTP_IMAGE_START     0
@@ -46,6 +48,9 @@

     ngx_flag_t                   transparency;

+    ngx_str_t                    watermark;
+    ngx_str_t                    watermark_position;
+
     ngx_http_complex_value_t    *wcv;
     ngx_http_complex_value_t    *hcv;
     ngx_http_complex_value_t    *acv;
@@ -150,6 +155,20 @@
       offsetof(ngx_http_image_filter_conf_t, buffer_size),
       NULL },

+    { ngx_string("image_filter_watermark"),
+     
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_image_filter_conf_t, watermark),
+      NULL },
+
+    { ngx_string("image_filter_watermark_position"),
+     
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_image_filter_conf_t, watermark_position),
+      NULL },
+
       ngx_null_command
 };

@@ -518,6 +537,15 @@
         return ngx_http_image_resize(r, ctx);
     }

+    if (conf->filter == NGX_HTTP_IMAGE_WATERMARK) {
+
+        if (!conf->watermark.data) {
+            return NULL;
+        }
+
+        return ngx_http_image_resize(r, ctx);
+    }
+
     ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv,
conf->width);
     if (ctx->max_width == 0) {
         return NULL;
@@ -813,6 +841,10 @@

         resize = 0;

+    } else if (conf->filter == NGX_HTTP_IMAGE_WATERMARK) {
+
+        resize = 0;
+
     } else { /* NGX_HTTP_IMAGE_CROP */

         resize = 0;
@@ -958,6 +990,40 @@
         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;
+              }
+              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);
@@ -1223,6 +1289,11 @@
     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
                               1 * 1024 * 1024);

+    ngx_conf_merge_str_value(conf->watermark, prev->watermark, "");
+
+    ngx_conf_merge_str_value(conf->watermark_position,
+                             prev->watermark_position, "bottom-right");
+
     return NGX_CONF_OK;
 }

@@ -1252,6 +1323,9 @@
         } else if (ngx_strcmp(value[i].data, "size") == 0) {
             imcf->filter = NGX_HTTP_IMAGE_SIZE;

+        } else if (ngx_strcmp(value[i].data, "watermark") == 0) {
+            imcf->filter = NGX_HTTP_IMAGE_WATERMARK;
+
         } else {
             goto failed;
         }

Posted at Nginx Forum: http://forum.nginx.org/read.php?21,235958,235958#msg-235958



Подробная информация о списке рассылки nginx-ru