Skip to content

Commit d1afb80

Browse files
committed
png: enable to write transparent image with :background
1 parent caa563b commit d1afb80

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

irteus/euspng.c

+35-3
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,46 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
140140
char *file_name;
141141
png_bytep image_ptr;
142142
int width, height, channels;
143-
ckarg(5);
143+
pointer bg;
144+
ckarg2(5,6);
144145
if (isstring(argv[0])) file_name = (char *)(argv[0]->c.str.chars);
145146
else error(E_NOSTRING);
146147
width = ckintval(argv[1]);
147148
height = ckintval(argv[2]);
148149
channels = ckintval(argv[3]);
149-
image_ptr = (png_bytep)(argv[4]->c.str.chars);
150+
151+
if (n==6 && argv[5]!=NIL) { /* set background color */
152+
bg = argv[5];
153+
if (!isfltvector(bg)) error(E_NOVECTOR);
154+
if (3!=vecsize(bg)) error(E_VECSIZE);
155+
}else{
156+
bg=NIL;
157+
}
158+
159+
if(bg==NIL) {
160+
image_ptr = (png_bytep)(argv[4]->c.str.chars);
161+
} else {
162+
int x, y;
163+
png_byte bg_r=bg->c.fvec.fv[0]*255, bg_g=bg->c.fvec.fv[1]*255, bg_b=bg->c.fvec.fv[2]*255;
164+
image_ptr = malloc(width*height*4);
165+
for(y = 0; y < height; y++) {
166+
for(x = 0; x < width; x++) {
167+
png_byte r, g, b;
168+
r = ((png_bytep)(argv[4]->c.str.chars))[(y*width+x)*3+0];
169+
g = ((png_bytep)(argv[4]->c.str.chars))[(y*width+x)*3+1];
170+
b = ((png_bytep)(argv[4]->c.str.chars))[(y*width+x)*3+2];
171+
image_ptr[(y*width+x)*4+0] = r;
172+
image_ptr[(y*width+x)*4+1] = g;
173+
image_ptr[(y*width+x)*4+2] = b;
174+
image_ptr[(y*width+x)*4+3] = ((r==bg_r)&&(g==bg_g)&&(b==bg_b))?0:255;
175+
}
176+
}
177+
}
178+
150179
FILE *fp = fopen(file_name, "wb");
151180
if (!fp) {
152181
error(E_OPENFILE);
182+
if(bg!=NIL) {free(image_ptr);}
153183
return(NIL);
154184
}
155185

@@ -161,12 +191,13 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
161191
if (setjmp(png_jmpbuf(png_ptr))) {
162192
png_destroy_write_struct(&png_ptr, &info_ptr);
163193
fclose(fp);
194+
if(bg!=NIL) {free(image_ptr);}
164195
error(E_EOF);
165196
return(NIL);
166197
}
167198

168199
png_init_io(png_ptr, fp);
169-
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, //GRAY
200+
png_set_IHDR(png_ptr, info_ptr, width, height, 8, (bg==NIL)?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_RGB_ALPHA, //GRAY
170201
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
171202
png_bytep * row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
172203
int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr);
@@ -183,6 +214,7 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
183214

184215
fclose(fp);
185216

217+
if(bg!=NIL) {free(image_ptr);}
186218
return (T);
187219
}
188220

irteus/irtimage.l

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@
6161
(t (warn ";; Could not find file ~A~%" fname)
6262
(return-from read-image-file nil))))
6363

64-
(defun write-image-file (fname img)
64+
(defun write-image-file (fname img &optional background)
6565
"write img to given fname"
6666
(cond
6767
((or (string= (pathname-type fname) "jpg")
6868
(string= (pathname-type fname) "jpeg"))
6969
(write-jpeg-file fname img))
7070
((string= (pathname-type fname) "png")
71-
(write-png-file fname img))
71+
(write-png-file fname img background))
7272
(t
7373
(write-pnm-file fname img))))
7474

irteus/irtviewer.l

+5-3
Original file line numberDiff line numberDiff line change
@@ -534,12 +534,14 @@
534534
(t "000000")))
535535
))
536536
(:save-image
537-
(filename)
538-
"save curent view to image, supported formats are jpg/png/pnm"
537+
(filename &key background)
538+
"save curent view to image, supported formats are jpg/png/pnm,
539+
png supports transparent image with background. To use this feature, set :change-background #f(0 1 0) and specify #f(0 1 0) as background"
539540
(user::write-image-file filename
540541
(send viewer :viewsurface :getglimage
541542
:width (- (send viewer :viewsurface :width) 1)
542-
:height (send viewer :viewsurface :height))))
543+
:height (send viewer :viewsurface :height))
544+
background))
543545
)
544546

545547
(defun draw-things (objs)

irteus/png.l

+3-2
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,15 @@
6262
img)
6363
nil))
6464

65-
(defun write-png-file (fname img)
65+
(defun write-png-file (fname img &optional background)
6666
(let (byte-depth)
6767
(cond
6868
((derivedp img grayscale-image) (setq byte-depth 1))
6969
((derivedp img color-image24) (setq byte-depth (send img :byte-depth)))
7070
(t (error ";; write-png-file: unsupported image type ~A" img)))
7171
(png-write-image fname (send img :width) (send img :height) byte-depth
72-
(send img :entity))
72+
(send img :entity) background
73+
)
7374
))
7475

7576
(provide :png "@(#)$Id$")

0 commit comments

Comments
 (0)