📄 gtk_tut-13.html
字号:
implementation of reducing the image. (Keep in mind that I've had only basicC!)(UNTESTED CODE ALERT!!!)typedef struct { gint width; gint height; gint bbp; guchar *rgb; guchar *mask;} ReducedImage;enum { SELECTION_ONLY, SELCTION_IN_CONTEXT, ENTIRE_IMAGE};ReducedImage *Reduce_The_Image(GDrawable *drawable, GDrawable *mask, gint LongerSize, gint Selection){ /* This function reduced the image down to the the selected preview size */ /* The preview size is determine by LongerSize, i.e. the greater of the */ /* two dimentions. Works for RGB images only! */ gint RH, RW; /* Reduced height and reduced width */ gint width, height; /* Width and Height of the area being reduced */ gint bytes=drawable->bpp; ReducedImage *temp=(ReducedImage *)malloc(sizeof(ReducedImage)); guchar *tempRGB, *src_row, *tempmask, *src_mask_row,R,G,B; gint i, j, whichcol, whichrow, x1, x2, y1, y2; GPixelRgn srcPR, srcMask; gint NoSelectionMade=TRUE; /* Assume that we're dealing with the entire */ /* image. */ gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2); width = x2-x1; height = y2-y1; /* If there's a SELECTION, we got its bounds!) if (width != drawable->width && height != drawable->height) NoSelectionMade=FALSE; /* Become aware of whether the user has made an active selection */ /* This will become important later, when creating a reduced mask. */ /* If we want to preview the entire image, overrule the above! */ /* Of course, if no selection has been made, this does nothing! */ if (Selection==ENTIRE_IMAGE) { x1=0; x2=drawable->width; y1=0; y2=drawable->height; } /* If we want to preview a selection with some surronding area we */ /* have to expand it a little bit. Consider it a bit of a riddle. */ if (Selection==SELECTION_IN_CONTEXT) { x1=MAX(0, x1-width/2.0); x2=MIN(drawable->width, x2+width/2.0); y1=MAX(0, y1-height/2.0); y2=MIN(drawable->height, y2+height/2.0); } /* How we can determine the width and the height of the area being */ /* reduced. */ width = x2-x1; height = y2-y1; /* The lines below determine which dimension is to be the longer */ /* side. The idea borrowed from the supernova plug-in. I suspect I */ /* could've thought of it myself, but the truth must be told. */ /* Plagiarism stinks! */ if (width>height) { RW=LongerSize; RH=(float) height * (float) LongerSize/ (float) width; } else { RH=LongerSize; RW=(float)width * (float) LongerSize/ (float) height; } /* The intire image is stretched into a string! */ tempRGB = (guchar *) malloc(RW*RH*bytes); tempmask = (guchar *) malloc(RW*RH); gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE); /* Grab enough to save a row of image and a row of mask. */ src_row = (guchar *) malloc (width*bytes); src_mask_row = (guchar *) malloc (width); for (i=0; i < RH; i++) { whichrow=(float)i*(float)height/(float)RH; gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1+whichrow, width); gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1+whichrow, width); for (j=0; j < RW; j++) { whichcol=(float)j*(float)width/(float)RW; /* No selection made = each point is completely selected! */ if (NoSelectionMade) tempmask[i*RW+j]=255; else tempmask[i*RW+j]=src_mask_row[whichcol]; /* Add the row to the one long string which now contains the image! */ tempRGB[i*RW*bytes+j*bytes+0]=src_row[whichcol*bytes+0]; tempRGB[i*RW*bytes+j*bytes+1]=src_row[whichcol*bytes+1]; tempRGB[i*RW*bytes+j*bytes+2]=src_row[whichcol*bytes+2]; /* Hold on to the alpha as well */ if (bytes==4) tempRGB[i*RW*bytes+j*bytes+3]=src_row[whichcol*bytes+3]; } } temp->bpp=bytes; temp->width=RW; temp->height=RH; temp->rgb=tempRGB; temp->mask=tempmask; return temp;}The following is a preview function which used the same ReducedImage type!Note that it uses fakes transparancy (if one is present by means offake_transparancy which is defined as follows:gint fake_transparency(gint i, gint j){ if ( ((i%20)- 10) * ((j%20)- 10)>0 ) return 64; else return 196;}Now here's the preview function:voidmy_preview_render_function(GtkWidget *preview, gint changewhat, gint changewhich){ gint Inten, bytes=drawable->bpp; gint i, j, k; float partial; gint RW=reduced->width; gint RH=reduced->height; guchar *row=malloc(bytes*RW);; for (i=0; i < RH; i++) { for (j=0; j < RW; j++) { row[j*3+0] = reduced->rgb[i*RW*bytes + j*bytes + 0]; row[j*3+1] = reduced->rgb[i*RW*bytes + j*bytes + 1]; row[j*3+2] = reduced->rgb[i*RW*bytes + j*bytes + 2]; if (bytes==4) for (k=0; k<3; k++) { float transp=reduced->rgb[i*RW*bytes+j*bytes+3]/255.0; row[3*j+k]=transp*a[3*j+k]+(1-transp)*fake_transparency(i,j); } } gtk_preview_draw_row( GTK_PREVIEW(preview),row,0,i,RW); } free(a); gtk_widget_draw(preview,NULL); gdk_flush();}Applicable Routinesguint gtk_preview_get_type (void);/* No idea */void gtk_preview_uninit (void);/* No idea */GtkWidget* gtk_preview_new (GtkPreviewType type);/* Described above */void gtk_preview_size (GtkPreview *preview, gint width, gint height);/* Allows you to resize an existing preview. *//* Apparantly there's a bug in GTK which makes *//* this process messy. A way to clean up a mess *//* is to manually resize the window containing *//* the preview after resizing the preview. */void gtk_preview_put (GtkPreview *preview, GdkWindow *window, GdkGC *gc, gint srcx, gint srcy, gint destx, gint desty, gint width, gint height);/* No idea */void gtk_preview_put_row (GtkPreview *preview, guchar *src, guchar *dest, gint x, gint y, gint w);/* No idea */void gtk_preview_draw_row (GtkPreview *preview, guchar *data, gint x, gint y, gint w);/* Described in the text */void gtk_preview_set_expand (GtkPreview *preview, gint expand);/* No idea *//* No clue for any of the below but *//* should be standard for most widgets */void gtk_preview_set_gamma (double gamma);void gtk_preview_set_color_cube (guint nred_shades, guint ngreen_shades, guint nblue_shades, guint ngray_shades);void gtk_preview_set_install_cmap (gint install_cmap);void gtk_preview_set_reserved (gint nreserved);GdkVisual* gtk_preview_get_visual (void);GdkColormap* gtk_preview_get_cmap (void);GtkPreviewInfo* gtk_preview_get_info (void);That's all, folks!</PRE></CODE></BLOCKQUOTE><P><P><H2><A NAME="ss13.7">13.7 Curves</A></H2><P><P><HR><A HREF="gtk_tut-12.html" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/gtk_tut-12.html"><IMG SRC="prev.gif" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/prev.gif" ALT="Previous"></A><A HREF="gtk_tut-14.html" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/gtk_tut-14.html"><IMG SRC="next.gif" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/next.gif" ALT="Next"></A><A HREF="gtk_tut.html#toc13" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/gtk_tut.html#toc13"><IMG SRC="toc.gif" tppabs="http://extend.hk.hi.cn/%7ehusuyu/http/beginner/gtk/toc.gif" ALT="Contents"></A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -