In gimp, I have about 98 layers. I have a path that I would like to stroke on across all the layers. Is there a way to do this without individually going through each layer?
You can do that easily using the Python console. I have a couple answers around with longer or shorter hints on how to use it -this is one: https://superuser.com/questions/1067478/how-to-change-several-images-in-gimp-that-are-already-open/1067867?noredirect=1
In this case, after having made a call to gimp.image_list() and selecting your target image in that list, assigning it to a image variable, just do a call to pdb.gimp_edit_stroke_vectors(...) for each layer on the images.
Therefore, your whole filters->Python-fu->Console sessions might be something along:
image = gimp.image_list()[0]
for layer in image.layers:
pdb.gimp_edit_stroke_vectors(layer, image.vectors[0])
(if your image is the last one openned (then its position on the image_list will be '0' ) and if your path is the topmost one on the paths dialog (which also will have '0' as an index).
You can use calls to pdb.gimp_context_set_foreground (or ...set_brush, and ...set_dynamics, ..set_brush_size) inside the for loop to change the respective settings as you progress through the layers, although there is no call to change the active tool. Use the "browse" button on the bottom of the Python console dialog to learn about all possible calls.
Related
The hierarchy I'm using looks something like this:
FRONT
1 - layer with several features (e.g. point data)
2 - layer with several features (e.g. path data)
3 - layer with several features (e.g. region data)
BACK
When the user selects a feature in layer 3 based on an ol.interaction.Select the default behavior is to render the selected feature in front of layer 1. How can I prevent this re-ordering?
I had a nearly similiar problem, when i selected the region - the points and other vector geometries were hidden behind the selected feature. In my usecase an special styling with transparent filling was the solution.
If you want a solution based on the layer rendering i would suggest to handle it with the ZIndex. The ol.interaction.Select doesn't provide a setZIndex but if you take a look on the source code (https://github.com/openlayers/ol3/blob/v3.13.0/src/ol/interaction/selectinteraction.js) you can see that the interaction save the selected feature in an unmanaged Layer which you can access on different ways (map.getLayers().getArray().forEach .... or sth) and i'm sure there you can set the ZIndex. Note default zIndex is 0 and a higher Index will render the layer above and lower one.
Here's how the select interaction works in ol3. The selected feature is marked for being skipped in rendering. In other words, it disappears from the original layer it comes from upon re-rendering after being selected.
It is then added to an other layer that is actually not added to the map using the conventional map.addLayer method, but set to the map using layer.setMap. The layer ends up being drawn on top of all the others, resulting the "selected" feature to be on top of everything else.
This architecture was decided to improve performance. However, you can easily achieve what you want, i.e. have the clicked feature stay where it is and change its style, by simply using the map.forEachFeatureAtPixel method and implement your own concept of selection there. It would be slower, but simple enough to accomplish what you want.
I've large set of images. I wan't to chage their background to specific color. Lets say green. All of the images have transparent background. Is there a way to perform this action using python-fu scripting in Gimp. Or some other tool available to do this specific task in automated fashion.
Yes there is -
Although this question is not an exact duplicate, i is not practical to just type in the basics of creating a Python plug-in every time someone asks to automate some task in the GIMP
I will have to ask you to look at GIMP: Create image stack from all image files in folder and maybe some other python-fu related answers for the basics.
After you get a simple "hello world" script going, simply
register a script that asks for
a string with the desired folder, use Python's os.listdir, or glob.glob to fetch the paths
to the iamge files, and simply loop through them repeating calls to:
image = pdb.gimp_file_load (...)
image.new_layer(pos=1, fill_mode = FOREGROUND_FILL)
pdb.gimp_file_save(...)
pdb.gimp_image_delete(image)
The parameters to the PDB calls are easy to check at GIMP's help procedure browser -
the image's new_layermethod is not really documented, and can replace 3-4 pdb calls - the possible parameters to it are: "name", "width", "height", "offset_x", "offset_y",
"alpha", "pos", "opacity", "mode", "fill_mode",
all of which are optional. "pos" is the layer position: 0 is at the top of the image. "1" would be just bellow the topmost layer.
It should be clear that the gimp_image_delete call will just remove the image from memory - not the file from disk. Simply de-referencing it on the Python side won't make GIMP forget it. Likewise, if you want to interact with any image open in this way, you have to call pdb.gimp_display_new for that image.
You should be able to accomplish this by simply setting the background color to your desired color and then simply flatten the image which will make all transparent areas become set to the current background color.
pdb.gimp_palette_set_background( 'green' )
image = pdb.gimp_file_load ('myImage.png')
flatLayer = pdb.gimp_image_flatten( image )
pdb.gimp_file_save( image, flatLayer, 'myFlatFile.png' , 'myFlatFile.png')
I'm currently trying to find a neat way of storing separate "branches" in a binary image. This little animation explains it:
As I go along the branches I need to collect the pixel indices that makes up a single-pixel wide branch. When I hit a junction point it should split up and store the new branches.
One way of going about it is maybe to create a 3x3 subregion, find out if there are white pixels inside it, move it accordingly, create a junction point if there is more than two. Always store the previous subregion so one can use it for making sure that we don't move to regions we already scanned.
It's a bit tricky to figure out how I would go about it though.
I basically need to reorder the pixels based on a "line/curve" hierarchy. Another part of the application will then redraw the figures, which internally works by creating lines between points hence the need to have them "ordered".
I don't know if you could apply it in your case but you should take a look at cv::findContour.
you will get a vector of points ordered.
http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html
I have a task where I need to track a series of objects across several frames, and compose the background from the image. The issue arises because one of the objects does not move until near the end, so I'm forced to take a shoddy average of the image. However, if I can blur out the objects, I think I'll be able to improve the background average.
I can identify a subsection of the image where the object is, an m by m array. I just need the ability to blur out this section with a filter. However, imfilter uses a fullsized array (image) as its input, so I cannot simply move along this array pixel by pixel in a for loop. But, if I try removing the image to take an image, I cannot put it back in without using another for loop, which would be computational expensive.
Is there a method of mapping a blur to a subsection of an image using MATLAB? Can this be done without using two for loops?
Try this...
sub_image = original_image(ii:jj,mm:nn)
blurred_sub_image = imfilter(sub_image, etc)
original_iamge(ii:jj,mm:nn) = blurred_sub_image
In short, you don't need to use a for loop to address a subsection of an image. You can do it directly, both for reading and writing.
I have two images that I want to display on top of each other. one image a single channel image and the second image is a RGB image but with most of the area being transparent.
How these two images are generated in different functions. I know to just display these on top of each other, i can use the same window name when calling cvShowImage() but this doesn't work when they are drawn from different functions. When trying this, I used cvCvtcolor() to convert he binary image from single channel to RGB and then displaying the second image from another function. But this didn't work. Both images are same dimension, depth and number of channels (after conversion).
I want to avoid passing in one image into the second function and then draw them. So I'm looking for a quick dirty trick to display these two images overlapped.
Thank you
EDIT:
I don't think that's possible. You'll have to create a new image or modify an existing one. Here's an article that shows how to do this: Transparent image overlays in OpenCV
There is no way to "overlay" images. cvShowImage() displays a single image from memory. You'll need to blend/combine them together. There are several ways to do this.
You can copy one into 1 or 2 channels of the other, you can use logical operations like AND, OR or XOR, you can use arithmetic operations like Add, Multiply and MultiplyScale (these operations will saturate values larger than 255). All these can also be done with an optional mask image like your blob image.
Naturally, you may want to do this into a third buffer so as not to overwrite your originals.
Apparently now it can be done using OpenCV 2.1 version
http://opencv.willowgarage.com/documentation/cpp/highgui_qt_new_functions.html#cv-displayoverlay