 |
| Script Coder |
 |
Joined: May 07, 2014 Posts: 4557 Location: Canada
|
I googled this because I know it existed before and did it probably from this same page: Fast Pixel Ops in GIMP-Python ( https://shallowsky.com/blog/gimp/pygimp-pixel-ops.html) But in the example there's a missing part which is updating the destination layer after the work has been done which is found at ( https://github.com/akkana/gimp-plugins/ ... rclayer.py) by the same author which was linked in 1st post as well but I didn't know this when working with it so spent some time fighting. But it's this piece of code: destDrawable.flush() destDrawable.merge_shadow(True) destDrawable.update(0, 0, newWidth,newHeight)
So together I created a test py that uses the above technique for fast pixel operations (code below): Have an image with 2 layers, select the layer you want to copy or flip 2 directions, vertical and horizontal Plug-in will allow you to choose a destination layer to have result shown on using fast pixel operations. That's it. it's SUPER FAST like about 1 second to do on a large 2000 x 2000 or so image. #!/usr/bin/env python # test-fast-pixel.py # fast-pixel test based on instructions shown on this webpage: https://shallowsky.com/blog/gimp/pygimp-pixel-ops.html # Created by TT # Just a test # # Comments directed to http://gimpchat.com or http://gimp-forum.net or http://gimpscripts.com # # License: GPLv3 # 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 3 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. # # To view a copy of the GNU General Public License # visit: http://www.gnu.org/licenses/gpl.html # # # ------------ #| Change Log | # ------------ # Rel 1: Initial release. import math import random from gimpfu import * from array import array #fast pixel operations need this
def test_command(image,layer,dest): #[ ... setting up ... ] # initialize the regions and get their contents into arrays: srcWidth = layer.width srcHeight = layer.height srcRgn = layer.get_pixel_rgn(0, 0, srcWidth, srcHeight,False, False) src_pixels = array("B", srcRgn[0:srcWidth, 0:srcHeight]) newWidth = dest.width newHeight = dest.height dstRgn = dest.get_pixel_rgn(0, 0, newWidth, newHeight,True, True) p_size = len(srcRgn[0,0]) dest_pixels = array("B", "\x00" * (newWidth * newHeight * p_size)) #[ ... then inside the loop over x and y ... ] pdb.gimp_message(p_size) x = 0; y = 0; src_pos = (x + srcWidth * y) * p_size newval = src_pixels[src_pos: src_pos + p_size]
pdb.gimp_message(newval[0]) for y in range(0,srcHeight): pdb.gimp_progress_update(float(y)/srcHeight) for x in range(0,srcWidth): #The below 2 lines are like newval = getpixel(x,y) src_pos = (x + srcWidth * y) * p_size newval = src_pixels[src_pos: src_pos + p_size] newx = newWidth - x - 1 newy = newHeight - y - 1 #The below 2 lines are like setpixel(x,y,newvalue) dest_pos = (newx + newWidth * newy) * p_size dest_pixels[dest_pos : dest_pos + p_size] = newval
#[ ... when the loop is all finished ... ] # Copy the whole array back to the pixel region: pdb.gimp_message(len(dstRgn[0:newWidth, 0:newHeight])) pdb.gimp_message(len(dest_pixels.tostring())) dstRgn[0:newWidth, 0:newHeight] = dest_pixels.tostring() #need this to update layer dest.flush() dest.merge_shadow(True) dest.update(0, 0, newWidth,newHeight) register( "python_fu_a_fast_pixel_test", "Fast Pixel Test", "Fast Pixel Test", "TT", "TT", "2024.1.1", "A Fast Pixel Test", "", # Alternately use RGB, RGB*, GRAY*, INDEXED etc. [ #INPUT BEGINS (PF_IMAGE, "image", "IMAGE:", None), # should be type gimp.image, but None works (PF_DRAWABLE, "layer", "Source Layer:", None), (PF_DRAWABLE, "dest", "Dest Layer:", None), #INPUT ENDS ], [], test_command, menu="<Image>/Python-Fu")
main() # Below is all the example input types for INPUTS for the plug-in which can be cut and pasted into #INPUT BEGINS section and edited to taste # (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32 similar but no difference in Python. # (PF_FLOAT, "p02", "_FLOAT:", 3.141), # (PF_STRING, "p03", "_STRING:", "foo"), # alias PF_VALUE # (PF_TEXT, "p04", "TEXT:", "bar"), # # PF_VALUE # # Pick one from set of choices # (PF_OPTION,"p1", "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice # (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons # # PF_RADIO is usually called a radio button group. # # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step). # (PF_TOGGLE, "p2", "TOGGLE:", 1), # initially True, checked. Alias PF_BOOL # # PF_TOGGLE is usually called a checkbox. # (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)), # (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)), # alias PF_ADJUSTMENT # # Pickers ie combo boxes ie choosers from lists of existing Gimp objects # (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple # # PF_COLOUR is an alias by aussie PyGimp author lol # (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works # (PF_FONT, "p17", "FONT:", 0), # (PF_FILE, "p18", "FILE:", 0), # (PF_BRUSH, "p19", "BRUSH:", 0), # (PF_PATTERN, "p20", "PATTERN:", 0), # (PF_GRADIENT, "p21", "GRADIENT:", 0), # (PF_PALETTE, "p22", "PALETTE:", 0), # (PF_LAYER, "p23", "LAYER:", None), # (PF_CHANNEL, "p24", "CHANNEL:", None), # ??? Usually empty, I don't know why. # (PF_DRAWABLE, "p25", "DRAWABLE:", None), # # Mostly undocumented, but work # (PF_VECTORS, "p26", "VECTORS:", None), # (PF_FILENAME, "p27", "FILENAME:", 0), # (PF_DIRNAME, "p28", "DIRNAME:", 0) # # PF_REGION might work but probably of little use. See gimpfu.py.
_________________
 Visualize your and others dreams coming true.
|
|