📄 gtk_tut_it-12.html
字号:
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){ /* Questa funzione riduce l'immagine alla dimens. scelta per l'anteprima */ /* La dimensione dell'anteprima è determinata da LongerSize, cioè la più */ /* grande delle dimensioni. Funziona solo per immagini RGB! */ gint RH, RW; /* Altezza ridotta e larghezza ridotta */ gint width, height; /* Larghezza e altezza dell'area da ridurre */ 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; /* Assumiamo di trattare l'intera immagine */ gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2); width = x2-x1; height = y2-y1; /* Se c'è una SELEZIONE, ne abbiamo avuto gli estremi! */ if (width != drawable->width && height != drawable->height) NoSelectionMade=FALSE; /* Controlliamo se l'utente ha una selezione attiva. Questo */ /* diventerà importante dopo, alla creazione di una maschera ridotta */ /* Se si vuole l'anteprima dell'immagine intera, annulla quanto sopra */ /* Naturalmente, in assenza di una selezione, questo non cambia nulla */ if (Selection==ENTIRE_IMAGE) { x1=0; x2=drawable->width; y1=0; y2=drawable->height; } /* Se si vuole l'anteprima di una selezione con parte dell'area */ /* circostante bisogna espanderla un po'. */ 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); } /* Così si determinano larghezza e altezza dell'area da ridurre. */ width = x2-x1; height = y2-y1; /* Le linee seguenti determinano quale dimensione deve essere il */ /* lato più lungo. L'idea è presa dal plug-in supernova. Ritengo */ /* che avrei potuto pensarci da solo, ma la verità va detta. */ /* Brutta cosa il plagio! */ if (width>height) { RW=LongerSize; RH=(float) height * (float) LongerSize/ (float) width; } else { RH=LongerSize; RW=(float)width * (float) LongerSize/ (float) height; } /* L'intera immagine viene "stirata" in una stringa! */ 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); /* Prendine abbastanza da contenere una riga di immagine e una di maschera */ 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; /* Nessuna selezione = tutti i punti sono completamente selezionati */ if (NoSelectionMade) tempmask[i*RW+j]=255; else tempmask[i*RW+j]=src_mask_row[whichcol]; /* Aggiungi la riga alla lunga stringa che ora contiene l'immagine */ 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]; /* Mantieni anche la trasparenza (alpha) */ 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;}</PRE></CODE></BLOCKQUOTE><P><P>La seguente è una funzione di anteprima che usa lo stesso tipoReducedImage! Si noti che usa una finta trasparenza - se ne è presente una, tramite fake_transparency che è definita come segue:<P><BLOCKQUOTE><CODE><PRE>gint fake_transparency(gint i, gint j){ if ( ((i%20)- 10) * ((j%20)- 10)>0 ) return 64; else return 196;}</PRE></CODE></BLOCKQUOTE>E adesso la funzione per l'anteprima:<BLOCKQUOTE><CODE><PRE>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();}Funzioni Applicabiliguint gtk_preview_get_type (void);/* No idea */void gtk_preview_uninit (void);/* No idea */GtkWidget* gtk_preview_new (GtkPreviewType type);/* Descritta precedentemente */void gtk_preview_size (GtkPreview *preview, gint width, gint height);/* Permette di ridimensionare un'anteprima esistente *//* Pare che un bug in GTK renda disordinato questo *//* processo. Un modo di rimettere le cose a posto *//* è quello di ridimensionare manualmente *//* la finestra contenente l'anteprima dopo aver *//* ridimensionato l'anteprima. */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);/* Descritta nel testo */void gtk_preview_set_expand (GtkPreview *preview, gint expand);/* No idea *//* Nessun indizio per le seguenti, ma dovrebbero *//* essere standard per la maggior parte dei widget */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);E' tutto!</PRE></CODE></BLOCKQUOTE><P><H2><A NAME="ss12.3">12.3 Curve</A></H2><P><P><HR NOSHADE><A HREF="gtk_tut_it-13.html">Avanti</A><A HREF="gtk_tut_it-11.html">Indietro</A><A HREF="gtk_tut_it.html#toc12">Indice</A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -