fix [#27746] Black and White Render doesn't work and/or Saves as a Blank screen
authorCampbell Barton <ideasman42@gmail.com>
Fri, 24 Jun 2011 03:49:56 +0000 (03:49 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 24 Jun 2011 03:49:56 +0000 (03:49 +0000)
convert to grayscale when saving renders rather then only writing the red channel.

source/blender/blenlib/BLI_math_color.h
source/blender/blenlib/intern/math_color.c
source/blender/editors/render/render_opengl.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/divers.c
source/blender/render/intern/source/pipeline.c

index fe09706cb3d727c5db63ed9229fc39fb4da54b4b..a6a1238a0640c57048163a3aeaa9c7ad823121bb 100644 (file)
@@ -70,6 +70,7 @@ unsigned int rgb_to_cpack(float r, float g, float b);
 unsigned int hsv_to_cpack(float h, float s, float v);
 
 float rgb_to_grayscale(float rgb[3]);
+unsigned char rgb_to_grayscale_byte(unsigned char rgb[3]);
 
 /***************** Profile Transformations ********************/
 
index ef1d5da56d82146e477f16e3e1e767580e99afa3..93143eb7db3bce0ba63d7f7d9c4e3825d031cfde 100644 (file)
@@ -488,6 +488,11 @@ float rgb_to_grayscale(float rgb[3])
        return 0.3f*rgb[0] + 0.58f*rgb[1] + 0.12f*rgb[2];
 }
 
+unsigned char rgb_to_grayscale_byte(unsigned char rgb[3])
+{
+       return (76*(unsigned short)rgb[0] + 148*(unsigned short)rgb[1] + 31*(unsigned short)rgb[2]) / 255;
+}
+
 /* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */
 
 void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
index 98463ce955fe123522d620d0dccdb2d418ae591f..a55f9101a0f662a6614dbd0490f23c5fb02c2175 100644 (file)
@@ -220,6 +220,11 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
                if(oglrender->write_still) {
                        char name[FILE_MAX];
                        int ok;
+
+                       if(scene->r.planes == 8) {
+                               IMB_color_to_bw(ibuf);
+                       }
+
                        BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION, FALSE);
                        ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality); /* no need to stamp here */
                        if(ok)  printf("OpenGL Render written to '%s'\n", name);
@@ -433,6 +438,19 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
        ibuf= BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
 
        if(ibuf) {
+               short ibuf_free= FALSE;
+
+               /* color -> greyscale */
+               /* editing directly would alter the render view */
+               if(scene->r.planes == 8) {
+                       ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
+                       IMB_color_to_bw(ibuf_bw);
+                       // IMB_freeImBuf(ibuf); /* owned by the image */
+                       ibuf= ibuf_bw;
+
+                       ibuf_free= TRUE;
+               }
+
                if(BKE_imtype_is_movie(scene->r.imtype)) {
                        ok= oglrender->mh->append_movie(&scene->r, CFRA, (int*)ibuf->rect, oglrender->sizex, oglrender->sizey, oglrender->reports);
                        if(ok) {
@@ -453,6 +471,10 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
                                BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
                        }
                }
+
+               if(ibuf_free) {
+                       IMB_freeImBuf(ibuf);
+               }
        }
 
        BKE_image_release_ibuf(oglrender->ima, lock);
index e9592fdc164258484f423215a182bdf8be5ebbbb..ff01e3a8a1e7838a9a1118b7d9670e2ea7e7c00f 100644 (file)
@@ -338,6 +338,7 @@ void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
 /* note, check that the conversion exists, only some are supported */
 void IMB_convert_profile(struct ImBuf *ibuf, int profile);
 float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
+void IMB_color_to_bw(struct ImBuf *ibuf);
 
 /**
  * Change the ordering of the color bytes pointed to by rect from
index 90ee2692cf0323417dbf2af08fbdd8ed7ad87277..7fc7669601dcd9ecc054f7d58efb5cd20aca8c83 100644 (file)
@@ -490,3 +490,23 @@ float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
                return fbuf;
        }
 }
+
+
+/* no profile conversion */
+void IMB_color_to_bw(struct ImBuf *ibuf)
+{
+       float *rctf= ibuf->rect_float;
+       unsigned char *rct= (unsigned char *)ibuf->rect;
+       int i;
+       if(rctf) {
+               for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
+                       rctf[0]= rctf[1]= rctf[2]= rgb_to_grayscale(rctf);
+               }
+       }
+
+       if(rct) {
+               for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
+                       rct[0]= rct[1]= rct[2]= rgb_to_grayscale_byte(rct);
+               }
+       }
+}
index 2a47a2db0ffcf745dc4ee15d48fb37d550423bdf..1d112341218006ccf1ef4bcdc950fd807d7b6fac 100644 (file)
@@ -2995,6 +2995,15 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, R
                                }
                        }
 
+                       /* color -> greyscale */
+                       /* editing directly would alter the render view */
+                       if(scene->r.planes == 8) {
+                               ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
+                               IMB_color_to_bw(ibuf_bw);
+                               IMB_freeImBuf(ibuf);
+                               ibuf= ibuf_bw;
+                       }
+
                        ok= BKE_write_ibuf_stamp(scene, camera, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
                        
                        if(ok==0) {