; Tiles to Files, V1.0 ; ; http://flickr.com/photos/theilr, (c) 2009 ; ; DESCRIPTION: Partitions an image into tiles (with, optionally, ; either gaps or overlaps between them) and writes each tile as a ; separate jpeg file. Note, this is almost identical to the ; Image->Transform->Guillotine function ; ; ONE MOTIVATION: At winkflash today, you can buy 4x6 inch prints for ; six cents each; so you could buy 36 of them for $2.16, and tile an ; area of size 24x36 inches. But to buy a single 24x36 inch print ; will cost about $20. Of course, the two aren't exactly equivalent, ; but what this script provides is a quick way to produce the separate ; jpeg files. ; ; USAGE NOTES: ; As well as generating the files, it (by default) also makes ; an auxiliary image in a new window where each tile is a separate ; layer. You can have that image deleted before you ever see it, but ; it might be useful if you want to check that the tiles are ; reasonable, or if you want to do some further processing to the ; individual tiles. Otherwise, you'll probably want to close that ; image, when you are sure that the jpegs are what you wanted. ; ; If you give a blank filename, then files are not generated. ; ; The tiles will always be the same size (this is not a bug) even if that ; means that a few pixels are dropped off the right or bottom margins. ; (By contrast, depending on how you do it, setting up guides and using ; Guillotine, will get all the pixels, but some images will be slightly ; different sizes.) ; ; BUGS: ; ; This is almost identical to a setting up of regular guides, followed ; by the Image->Transform->Guillotine function. eg, see ; ; http://registry.gimp.org/node/12003 ; http://registry.gimp.org/node/20826 ; ; The individual jpeg files lose the EXIF info from the original file. ; (I don't really understand all the parameters to file-jpeg-save; and ; I also remark that the Guillotine approach doesn't have this problem.) ; ; That the output can only be jpeg is probably a bug; the user might ; prefer other file formats, or (at the least) to be able to adjust ; the jpeg quality parameter. ; ; If you give a blank filename AND you check the toggle to delete the ; image of tiles, then this script will do a lot of work and not have ; anything to show for it! ; ; It might be better to do this in two steps. First generate the image ; of tiles. Then (if you are happy with them) generate the files. A ; separate routine that did layers-to-files might be useful in its own ; right. ; ; Only works on RGB images; should probably extend to GRAYSCALE, etc. ; ; I've limited this to 100x100 tiles. It's an arbitrary limit, but ; I'd think it should be plenty. ; ; The number of overlap/gao pixels is limited to 200, again arbitrary ; and capricious. Also, the number is the same for horizontal and ; vertical. I can see where a percentage might be preferable. ; ; Negative overlap may not be the most intuitive way to make gaps. ; ; It might be cool to have an option to add some kind of border to ; all of the images. ; ; Height and Horizontal both start with the letter H; that's not my ; fault, but it can lead to ambiguities with abbreviations. ; ; TESTING: ; This script was tested with GIMP 2.6.7 ; ; COPYLEFT: ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License Version 3 as ; published by the Free Software Foundation. ; ; 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 at http://www.gnu.org/licenses for ; more details. ; ; MENU LOCATION: ; The script is located in menu " / Filters / theilr / Tiles to Files" ; But you will probably want to change that. ; ; Version 1.0 (Nov 2009) ; ============================================================================= (define (script-fu-tiles-to-files inImage inLayer inHTiles inVTiles inOverlapPixels inFilePrefix inDeleteImage) (gimp-image-undo-group-start inImage) (let* ( (fullWidth (car (gimp-image-width inImage))) (fullHeight (car (gimp-image-height inImage))) (tileWidth (+ inOverlapPixels (/ (- fullWidth inOverlapPixels) inHTiles))) (tileHeight (+ inOverlapPixels (/ (- fullHeight inOverlapPixels) inVTiles))) (newImage (car (gimp-image-new tileWidth tileHeight RGB))) (hcnt 0) (vcnt 0) (tmpLayer) (selLayer) (outfname) ) (set! vcnt 0) (while (< vcnt inVTiles) (set! hcnt 0) (while (< hcnt inHTiles) (set! outfname (string-append inFilePrefix "-" (number->string vcnt) "-" (number->string hcnt) ".jpg")) (gimp-rect-select inImage (* (- tileWidth inOverlapPixels) hcnt) (* (- tileHeight inOverlapPixels) vcnt) tileWidth tileHeight CHANNEL-OP-ADD FALSE 0) (gimp-edit-copy-visible inImage) (gimp-selection-none inImage) (set! tmpLayer (car (gimp-layer-new newImage tileWidth tileHeight RGB-IMAGE outfname 100 NORMAL-MODE))) (gimp-image-add-layer newImage tmpLayer -1) (set! selLayer (car (gimp-edit-paste tmpLayer FALSE))) (gimp-floating-sel-anchor selLayer) ;; if filename is empty, don't write jpeg files (unless (equal? "x" (string-append "x" inFilePrefix)) (file-jpeg-save RUN-NONINTERACTIVE newImage tmpLayer outfname outfname 1 0 1 1 "tile" 0 1 0 0 ) ) (set! hcnt (+ hcnt 1)) ) (set! vcnt (+ vcnt 1)) ) ;; either delete the new image, or display it (if (= inDeleteImage TRUE) (gimp-image-delete newImage) (gimp-display-new newImage)) (gimp-image-undo-group-end inImage) (gimp-displays-flush) ) ) (script-fu-register "script-fu-tiles-to-files" "/Filters/theilr/_Tiles to Files" "Partition image into a grid of tiles,\n\ and save each tile to a separate jpeg file" "www.flickr.com/photos/theilr" "(c) theilr" "November 2009" "RGB*" SF-IMAGE "Image" 0 SF-DRAWABLE "Drawable" 0 SF-ADJUSTMENT "Number of Horizontal tiles" '(3 1 100 1 10 0 SF-SPINNER) SF-ADJUSTMENT "Number of Vertical tiles" '(3 1 100 1 10 0 SF-SPINNER) SF-ADJUSTMENT "Gap(neg)/Overlap(pos) pixels" '(0 -200 200 1 10 0 SF-SLIDER) SF-STRING "Output filename prefix" "" SF-TOGGLE "Delete auxiliary image" FALSE )