Add new directive '2square' to image_filter, which resizes and converts
image in square and add white border. It's cood be usefull for convert
image for facebook banners.

In attach:
nginx.patch - patch for main repo (http://hg.nginx.org/nginx),
image_filter_2square.t -  file with tests for (http://hg.nginx.org/nginx-
tests)
nginx_org.patch - docs for (http://hg.nginx.org/nginx.org/)

-- 
С уважением,
Иванов Иван



-- 
С уважением,
Иванов Иван
# HG changeset patch
# User Ivan Ivanov <[email protected]>
# Date 1498645987 -10800
#      Wed Jun 28 13:33:07 2017 +0300
# Node ID 0e29d2775b635ff0648c11b28daae0843d7bebd8
# Parent  a1c6685e80cba59284fc5e500818ea3b871403eb
Add directive '2square' to image_filter, which resizes and converts in square

diff -r a1c6685e80cb -r 0e29d2775b63 src/http/modules/ngx_http_image_filter_module.c
--- a/src/http/modules/ngx_http_image_filter_module.c	Tue Jun 27 17:44:18 2017 +0300
+++ b/src/http/modules/ngx_http_image_filter_module.c	Wed Jun 28 13:33:07 2017 +0300
@@ -18,7 +18,7 @@
 #define NGX_HTTP_IMAGE_RESIZE    3
 #define NGX_HTTP_IMAGE_CROP      4
 #define NGX_HTTP_IMAGE_ROTATE    5
-
+#define NGX_HTTP_IMAGE_2SQUARE   6
 
 #define NGX_HTTP_IMAGE_START     0
 #define NGX_HTTP_IMAGE_READ      1
@@ -39,6 +39,8 @@
 
 typedef struct {
     ngx_uint_t                   filter;
+    ngx_uint_t                   size;
+    ngx_uint_t                   border;
     ngx_uint_t                   width;
     ngx_uint_t                   height;
     ngx_uint_t                   angle;
@@ -70,6 +72,8 @@
     ngx_uint_t                   height;
     ngx_uint_t                   max_width;
     ngx_uint_t                   max_height;
+    ngx_uint_t                   size;
+    ngx_uint_t                   border;
     ngx_uint_t                   angle;
 
     ngx_uint_t                   phase;
@@ -540,6 +544,21 @@
         return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
     }
 
+
+    if (conf->filter == NGX_HTTP_IMAGE_2SQUARE) {
+        ctx->size = conf->size;
+        ctx->border = conf->border;
+        ctx->max_width = ctx->max_height = 0;
+
+        if (ctx->width == ctx->height
+            && ctx->width < ctx->size
+            && ctx->border == 0) {
+            return ngx_http_image_asis(r, ctx);
+        }
+
+        return ngx_http_image_resize(r, ctx);
+    }
+
     ctx->angle = ngx_http_image_filter_get_value(r, conf->acv, conf->angle);
 
     if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {
@@ -825,7 +844,7 @@
     u_char                        *out;
     ngx_buf_t                     *b;
     ngx_uint_t                     resize;
-    gdImagePtr                     src, dst;
+    gdImagePtr                     src, dst, dst2;
     ngx_pool_cleanup_t            *cln;
     ngx_http_image_filter_conf_t  *conf;
 
@@ -877,6 +896,8 @@
     dx = sx;
     dy = sy;
 
+    resize = 0;
+
     if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
 
         if ((ngx_uint_t) dx > ctx->max_width) {
@@ -897,7 +918,7 @@
 
         resize = 0;
 
-    } else { /* NGX_HTTP_IMAGE_CROP */
+    } else if (conf->filter == NGX_HTTP_IMAGE_CROP) {
 
         resize = 0;
 
@@ -919,7 +940,65 @@
         }
     }
 
-    if (resize) {
+    if (conf->filter == NGX_HTTP_IMAGE_2SQUARE) {
+
+        ngx_uint_t offset = ctx->border;
+        ngx_uint_t limit_size = ctx->size;
+
+        ngx_uint_t max = (dx > dy) ? dx : dy;
+
+        if (max > limit_size) {
+            dy = sy * limit_size / max;
+            dx = sx * limit_size / max;
+            max = limit_size;
+
+            ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->connection->log, 0,
+                           "image filter 2square resize: %d x %d", dx, dy);
+
+            dst2 = ngx_http_image_new(r, dx, dy, palette);
+            if (dst2 == NULL) {
+                gdImageDestroy(src);
+                return NULL;
+            }
+
+            gdImageCopyResampled(dst2, src, 0, 0, 0, 0, dx, dy, sx, sy);
+
+            gdImageDestroy(src);
+        } else {
+            dst2 = src;
+        }
+
+        max += 2*offset;
+        int new_width = max;
+        int new_height = max;
+
+        dst = ngx_http_image_new(r, new_width, new_height, palette);
+
+        if (dst == NULL) {
+            gdImageDestroy(dst2);
+            return NULL;
+        }
+
+        gdImageFill(dst, 0, 0, gdImageColorAllocate(dst, 255, 255, 255));
+        gdImageCopy(
+                dst,
+                dst2,
+                (int)(new_width - dx) / 2,
+                (int)(new_height - dy) / 2,
+                0,
+                0,
+                dx,
+                dy
+        );
+
+        if (colors) {
+            gdImageTrueColorToPalette(dst, 1, 256);
+        }
+
+        gdImageDestroy(dst2);
+
+    } else if (resize) {
+
         dst = ngx_http_image_new(r, dx, dy, palette);
         if (dst == NULL) {
             gdImageDestroy(src);
@@ -1322,6 +1401,8 @@
             conf->filter = prev->filter;
             conf->width = prev->width;
             conf->height = prev->height;
+            conf->size = prev->size;
+            conf->border = prev->border;
             conf->angle = prev->angle;
             conf->wcv = prev->wcv;
             conf->hcv = prev->hcv;
@@ -1444,7 +1525,10 @@
         }
     }
 
-    if (ngx_strcmp(value[i].data, "resize") == 0) {
+    if (ngx_strcmp(value[i].data, "2square") == 0) {
+        imcf->filter = NGX_HTTP_IMAGE_2SQUARE;
+
+    } else if (ngx_strcmp(value[i].data, "resize") == 0) {
         imcf->filter = NGX_HTTP_IMAGE_RESIZE;
 
     } else if (ngx_strcmp(value[i].data, "crop") == 0) {
@@ -1471,9 +1555,18 @@
             goto failed;
         }
 
-        imcf->width = (ngx_uint_t) n;
+        if (imcf->filter != NGX_HTTP_IMAGE_2SQUARE) {
+            imcf->width = (ngx_uint_t) n;
+        } else {
+            imcf->size = (ngx_uint_t) n;
+        }
 
     } else {
+
+        if (imcf->filter == NGX_HTTP_IMAGE_2SQUARE) {
+            goto failed;
+        }
+
         imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
         if (imcf->wcv == NULL) {
             return NGX_CONF_ERROR;
@@ -1495,13 +1588,24 @@
     if (cv.lengths == NULL) {
         n = ngx_http_image_filter_value(&value[i]);
 
-        if (n == 0) {
+        if (imcf->filter != NGX_HTTP_IMAGE_2SQUARE) {
+
+            if (n == 0) {
+                goto failed;
+            }
+
+            imcf->height = (ngx_uint_t) n;
+
+        } else {
+            imcf->border = (ngx_uint_t) n;
+        }
+
+    } else {
+
+        if (imcf->filter == NGX_HTTP_IMAGE_2SQUARE) {
             goto failed;
         }
 
-        imcf->height = (ngx_uint_t) n;
-
-    } else {
         imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
         if (imcf->hcv == NULL) {
             return NGX_CONF_ERROR;
# HG changeset patch
# User Ivan Ivanov <[email protected]>
# Date 1498676719 -10800
#      Wed Jun 28 22:05:19 2017 +0300
# Node ID 1523e2237f230ebcb1503286cdb116261c36a31f
# Parent  b13d6412b335a02a6c98cb91db246b8571c9d522
documentation for image_filter 2square

diff -r b13d6412b335 -r 1523e2237f23 xml/en/docs/http/ngx_http_image_filter_module.xml
--- a/xml/en/docs/http/ngx_http_image_filter_module.xml	Wed Jun 28 19:12:25 2017 +0300
+++ b/xml/en/docs/http/ngx_http_image_filter_module.xml	Wed Jun 28 22:05:19 2017 +0300
@@ -76,6 +76,10 @@
     <literal>crop</literal>
     <value>width</value>
     <value>height</value></syntax>
+<syntax>
+    <literal>2square</literal>
+    <value>length of the side</value>
+    <value>border size</value></syntax>
 <default>off</default>
 <context>location</context>
 
@@ -133,6 +137,19 @@
 the rotation happens <emphasis>after</emphasis> reduction.
 </tag-desc>
 
+<tag-name><literal>2square</literal>
+    <value>length of the side</value>
+    <value>border size</value>
+</tag-name>
+<tag-desc>
+    If the image is larger than the specified length -
+    reduces the image saving proportions.
+    A square is formed by filling the empty space with a white color.
+    A white frame of the specified width is added (can be set to 0),
+    The side length of the resulting square will be equal to the size of the image
+    after conversion + two widths of the frame.
+</tag-desc>
+
 <tag-name><literal>crop</literal>
 <value>width</value>
 <value>height</value>
diff -r b13d6412b335 -r 1523e2237f23 xml/ru/docs/http/ngx_http_image_filter_module.xml
--- a/xml/ru/docs/http/ngx_http_image_filter_module.xml	Wed Jun 28 19:12:25 2017 +0300
+++ b/xml/ru/docs/http/ngx_http_image_filter_module.xml	Wed Jun 28 22:05:19 2017 +0300
@@ -76,6 +76,10 @@
     <literal>crop</literal>
     <value>ширина</value>
     <value>высота</value></syntax>
+<syntax>
+    <literal>2square</literal>
+    <value>длина стороны</value>
+    <value>ширина рамки</value></syntax>
 <default>off</default>
 <context>location</context>
 
@@ -134,6 +138,19 @@
 уменьшения размеров изображения.
 </tag-desc>
 
+<tag-name><literal>2square</literal>
+    <value>длина стороны</value>
+    <value>ширина рамки</value>
+</tag-name>
+<tag-desc>
+    если изображение больше указанной длины -
+    пропорционально уменьшает изображение.
+    Формируем квадрат, заполняя пустое пространство белым цветом.
+    Добавляется рамка указанной ширины (можно задать равной 0),
+    Длина стороны полученного квадрата будет равна размеру изображения
+    после преобразования + две ширины рамки.
+</tag-desc>
+
 <tag-name><literal>crop</literal>
 <value>ширина</value>
 <value>высота</value>

Attachment: image_filter_2square.t
Description: Troff document

_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to