Наложение watermark'и посредством nginx'а

Набросок патча который позволяет nginx’ом накладывать watermark’у. Данная реализация работает только при использовалии функии изменения размера изображения.

Для использования:

image_filter_watermark ;
image_filter_watermark_position top-left|top-right|bottom-right|bottom-left;

Проверялось только с версией 0.8.42

Код патча:

@@ -1,6 +1,8 @@

  /*
   * Copyright (C) Igor Sysoev
 + *
 + * watermark patch: Vadym Zakovinko
   */


 @@ -41,6 +43,9 @@
      ngx_int_t                    jpeg_quality;

      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;
 @@ -131,6 +136,20 @@
        NGX_HTTP_LOC_CONF_OFFSET,
        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
  };
 @@ -878,6 +897,37 @@
      if (transparent != -1 && colors) {
          gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
      }
 +
 +    if (conf->watermark.data) {
 +        FILE *watermark_file = fopen((const char *)conf->watermark.data, "r");
 +        if (watermark_file) {
 +            gdImagePtr watermark;
 +            watermark = gdImageCreateFromJpeg(watermark_file);
 +            ngx_int_t wdx, wdy = 0;
 +
 +            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(dst, watermark, wdx, wdy, 0, 0, watermark->sx,
 +                        watermark->sy);
 +        } else {
 +            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 +                "watermark file '%s' not found", conf->watermark.data);
 +        }
 +    }

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

 @@ -1114,7 +1164,12 @@

      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;
  }