On Sun, 2004-10-17 at 08:52, Fernando Sancho wrote: > Hi all. > > I'm new to the list. I have joined because I need help. > > I'm making a gimp-python scipt to create cross stitch patterns from an > image. Reading list's archives i've founded this > http://www.mail-archive.com/[EMAIL PROTECTED]/msg01127.html > > I don't know if Carol has completed his idea. By now, i'm evaluating > how much work can make gimp by itself. > > The feature that i can't find in gimp is to map an image with a custom > palette (DMC Floss colors). Gimp only allows me to convert from RGB to > Indexed mode, but it doesn't allow to choose a custom pallete with > more than 256 colours, and doesn't allow to choose the maximum number > of colours. > > Any help?
The good news is that there is already a script-fu script to do this. The bad news is that you can't use a palette with more than 256 colors, because the script quantizes the original image's color information by converting it to indexed, which allows only 8 bits worth of color information. I have attached the script - note that the default values aren't very good. Cross-stitch seems to need at least a larger brush (Circle 03) and longer stitches (9 pixels per stitch seemed to work). Keep trying until you get what you want. Be warned - use of this script may leave your original image in an unrecoverable state - better always work on a copy. HTH -- Jeff
;;; ;;; xstitch.scm - cross stitch, knitting, or nedlepoint pattern ;;; generator. Take a photo and make in into something you can stitch. ;;; ;;; ;;; Jeff Trefftzs <[EMAIL PROTECTED]> ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ;;; This version uses a suggestion from GSR to speed things up. ;;; By using a mask for the stitches instead of doing each one separately ;;; we get a huge speedup. ;;; TODO: Get smart about brush size; optimize the mask generation ;;; to pick up as many rows as have been done up to now for the select ;;; and move. ;;; Helper function to draw the stitches according to style selection (define (script-fu-xstitch-draw-stitches inChannel inWidth inPixels inStyle) (let* ( (brushparms (gimp-brushes-get-brush-data "")) ; brush details (brushwidth (nth 4 brushparms)) (brushheight (nth 5 brushparms)) (xoffset (/ brushwidth 2)) (yoffset (/ brushheight 2)) (y 0) (parray (cons-array 4 'double)) ; strokes here ) ;; Draw one row of stitches for the mask (set! x 0) (while (< x inWidth) ;; This sets up the parray to show needlepoint (cond ((= inStyle 0) ; Needlepoint? (aset parray 0 (+ x xoffset)) (aset parray 1 (- (+ y inPixels) yoffset)) (aset parray 2 (- (+ x inPixels) xoffset)) (aset parray 3 (+ y yoffset)) (gimp-paintbrush inChannel 0 ; Fade out (length parray) parray CONTINUOUS 0) ) ;; Cross Stitch here ((= inStyle 1) ; Cross Stitch (aset parray 0 (+ x xoffset)) (aset parray 1 (- (+ y inPixels) yoffset)) (aset parray 2 (- (+ x inPixels) xoffset)) (aset parray 3 (+ y yoffset)) (gimp-paintbrush inChannel 0 ; Fade out (length parray) parray CONTINUOUS 0) ;; Set up for the other line - reverse y coords (aset parray 1 (aref parray 3)) (aset parray 3 (- (+ y inPixels) yoffset)) (gimp-paintbrush inChannel 0 ; Fade out (length parray) parray CONTINUOUS 0) ) ;; Knitting here ((= inStyle 2) ; Knitting (aset parray 0 (+ x xoffset)) (aset parray 1 (- (+ y inPixels) yoffset)) ; lower left (aset parray 2 (+ x (/ inPixels 2))) ; halfway across (aset parray 3 (+ y yoffset)) ; top (gimp-paintbrush inChannel 0 ; Fade out (length parray) parray CONTINUOUS 0) (aset parray 0 (aref parray 2)) ; halfway across (aset parray 1 (aref parray 3)) ; and at top (aset parray 2 (- (+ x inPixels) xoffset)) ; right edge (aset parray 3 (- (+ y inPixels) xoffset)) ; up from bottom (gimp-paintbrush inChannel 0 ; Fade out (length parray) parray CONTINUOUS 0) ) ) ; end cond (set! x (+ x inPixels)) ) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Main Stitch Pattern Definition Function ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (script-fu-xstitch inImage inLayer inBrush ; the brush to use inPixPerStitch ; pixels per stitch inColors ; number of colors to use inPalette ; palette to select from inBG ; Background/Canvas color inStyle ; Needlepoint, Xstitch, Knit inSgauge ; stitches per inch inRgauge ; rows per inch ) (let* ( (width (car (gimp-image-width inImage))) (height (car (gimp-image-height inImage))) (pixels inPixPerStitch) (oldfg (car (gimp-palette-get-foreground))) (oldbg (car (gimp-palette-get-background))) (oldbrush (gimp-brushes-get-brush)) ; get all info on old brush (yscale (/ inRgauge inSgauge)) ; how much to stretch for knitting (newheight (* height yscale)) ) (;; gimp-undo-push-group-start => gimp-image-undo-group-start gimp-image-undo-group-start inImage) (gimp-palette-set-background inBG) ; selected background color ;; While needlepoint and cross-stitch use a square grid, knitting stitches ;; are usually more rectangular. Typically there are more rows/inch than ;; there are stitches/inch. (Substitute metric units if you prefer them). ;; But the pixelization plug-in assumes a square grid, so we have to ;; stretch the image in the direction of the smaller steps. (if (not (= inSgauge inRgauge)) (gimp-image-scale inImage width newheight) ) ;; Now pixelize the image (plug-in-pixelize RUN-NONINTERACTIVE inImage inLayer pixels) ;; Convert it to indexed (;; gimp-convert-indexed => gimp-image-convert-indexed gimp-image-convert-indexed inImage 0 ; No dithering, since we want pixelized MAKE-PALETTE ; create our own palette to start inColors ; using specified no of colors FALSE ; No alpha dither FALSE ; Remove unused colors "NONE") ; Ignored this time ;; The image now has a restricted set of colors in it. That won't ;; change if we convert it back to RGB, so we do that next. Then ;; we convert it back to indexed, this time using the destination ;; palette. This is the poor man's map to closest colors in palette ;; x. Think of this step as a placeholder where we wait for a ;; better way to match colors from a palette potentially > 256 colors. (;; gimp-convert-rgb => gimp-image-convert-rgb gimp-image-convert-rgb inImage) ;; And convert it back using the desired palette. (;; gimp-convert-indexed => gimp-image-convert-indexed gimp-image-convert-indexed inImage 0 ; still no dithering CUSTOM-PALETTE inColors FALSE FALSE inPalette) ;; Convert back to RGB again for further manipulations (;; gimp-convert-rgb => gimp-image-convert-rgb gimp-image-convert-rgb inImage) ;; Now let's try to rewrite each little block with a diagonal ;; line representing the stitch in the right color. Will we ;; need a background color, too? (let* ( ;; New variables for use in the stitch painting loop (maskchannel (car (gimp-channel-new inImage width newheight "Stitch Mask" 50 ; 50% opaque '(255 255 0)))) (stitchlayer (car (gimp-layer-new inImage width newheight (car (gimp-image-base-type inImage)) "Stitch Layer" 100 ; opaque NORMAL-MODE))) (stitchmask (car (gimp-layer-create-mask stitchlayer WHITE-MASK))) ) ;; Initialize the stitch layer (gimp-layer-add-alpha stitchlayer) (gimp-image-add-layer inImage stitchlayer 0) (gimp-drawable-fill stitchlayer BG-IMAGE-FILL) (gimp-palette-set-foreground '(255 255 255)) ; white (gimp-image-add-channel inImage maskchannel 0) ; add the channel (gimp-drawable-fill maskchannel FG-IMAGE-FILL) ; and make it white ;; Now add a layer mask to the stitch layer. This mask will ;; allow the underlying colors to show through, while outlining ;; the stitches themselves with the background color. (;; gimp-image-add-layer-mask => gimp-layer-add-mask gimp-layer-add-mask stitchlayer stitchmask) ;; FIX ME! Relate brush size to pixels, relate stroke length to ;; pixels, add error checking. Stroke should start inside the box, ;; finish inside the box, too. For cross-stitch, draw two strokes ;; in the form of an X. (gimp-brushes-set-brush (car inBrush)) ; use selected brush ;; Now draw a row of stitches across the maskchannel (gimp-palette-set-foreground '(0 0 0)) ; black (gimp-image-set-active-channel inImage maskchannel) ;; Call the stitch drawing routine to get the right kind of stitch. (script-fu-xstitch-draw-stitches maskchannel width pixels inStyle) ;; Now copy that row down the height of the image (set! y pixels) ; next row (while (< y newheight) (gimp-rect-select inImage 0 0 width y REPLACE FALSE 0) ; select some pixels (gimp-edit-copy maskchannel) ; copy the selection (gimp-selection-translate inImage 0 y) ; shift down (gimp-floating-sel-anchor (car (gimp-edit-paste maskchannel TRUE))) ; and paste back (set! y (+ y y)) ; move down by as much as we did ) ;; Now copy the maskchannel into the layermask. (gimp-selection-all inImage) ; select the whole thing (gimp-edit-copy maskchannel) ; copy to clipboard (gimp-floating-sel-anchor (car (gimp-edit-paste stitchmask TRUE))) ; paste into the layer mask (;; gimp-channel-set-visible => gimp-drawable-set-visible gimp-drawable-set-visible maskchannel FALSE) ; invisible ;; Finally convert it back to indexed again. Play with this ;; some more -- maybe all this back and forth from rgb to indexed ;; can be avoided. (;; gimp-convert-indexed => gimp-image-convert-indexed gimp-image-convert-indexed inImage 0 ; still no dithering CUSTOM-PALETTE inColors FALSE FALSE inPalette) ) ; end inner let ;; If we were knitting, the image must be rescaled to orig ;; dimensions (if (not (= inSgauge inRgauge)) (gimp-image-scale inImage width height) ; back to old size ) ;; Finished! Now clean up and exit. (gimp-selection-none inImage) ; release the selection ; (gimp-image-set-active-layer inImage inLayer) ; back to orig layer (gimp-palette-set-foreground oldfg) ; restore palette colors (gimp-palette-set-background oldbg) (gimp-brushes-set-brush (car oldbrush)) ; restore brush (;; gimp-undo-push-group-end => gimp-image-undo-group-end gimp-image-undo-group-end inImage) ; turn undo back on (gimp-displays-flush) ; and show the image ) ; end outer let* ) (script-fu-register "script-fu-xstitch" _"<Image>/Script-Fu/Alchemy/Cross Stitch ..." "Converts an image into a cross stitch pattern. The lower layer has the pattern, using just the number of colors you selected from the specified palette. Note: Do NOT select a palette with > 256 colors. It will crash the GIMP. The upper layer gives a preview of the finished work, drawing the threads with the selected brush, shaping the stitches to conform to the style of work: needlepoint, cross-stitch, knitting. Select the brush to be smaller than the pixels per stitch parameter for best results." "Jeff Trefftzs" "Copyright 2002, Jeff Trefftzs" "ENTER DATE HERE" "RGB* GRAY* INDEXED*" SF-IMAGE "The Image" 0 SF-DRAWABLE "The Layer" 0 SF-BRUSH "Brush to draw stitches" '("Circle (01)" 100 25 0) SF-ADJUSTMENT "Pixels per Stitch" '(4 1 999999 1 10 0 1) SF-ADJUSTMENT "Number of Colors" '(32 1 256 1 10 0 1) SF-STRING "Palette" "Bears" SF-COLOR "Background" '(0 0 0) ; black, usually SF-OPTION "Stitch Style" '("Needlepoint" "Cross-Stitch" "Knitting") SF-ADJUSTMENT "Stitch Gauge - Stitches per Inch" '(14 0.25 128 .1 1 4 1) SF-ADJUSTMENT "Row Gauge - Rows per Inch" '(14 0.25 128 .1 1 4 1) )
_______________________________________________ Gimp-user mailing list [EMAIL PROTECTED] http://lists.xcf.berkeley.edu/mailman/listinfo/gimp-user