I would like to load 2 jpg images with Gimp Python. Then the pictures should be compared pixel by pixel. If the pixel in picture 2 has a certain rgb value, the pixel in picture 1 should be colored. Before that, a user input should be made in which the start value can be entered.
I'm unsure if gimp python can do it all?
Primarily I search the commands:
- Load a picture
- User input
- Load pixel RGB value
- Change pixel RGB value
- Save image
Many thanks in advance
I first tried c ++, but handling pictures is not that easy. My teacher advised me to gimp. Schematic it should look like this:
#include <iostream> using namespace std; int main() { unsigned long long int startPixelBreite; unsigned long long int startPixelHoehe; int prozent; //EDIT: Load pic 1 //EDIT: load pic 2 //startpixel bestimmen durch usereingabe cout << "Startpixel Höhe" << endl; cin >> startPixelBreite; cout << "Startpixel Höhe" << endl; cin >> startPixelHoehe; //breite + Höhe von bild 1 auslesen endpixelBreite = startPixelBreite + bildBreite1 endpixelHoehe = startPixelHoehe + bildHoehe1 //ANFANG: Schleife für pixelzeile aktuellerPixelX = 0; //ANFANG schleife für pixel pixelreihe //pixelfarbebild1 einlesen /* pixelfarbebild1[0] = //rot pixelfarbebild1[1] = //grün pixelfarbebild1[2] = //blau */ //pixelfarbebild2 einlesen /* pixelfarbebild2[0] = //rot pixelfarbebild2[1] = //grün pixelfarbebild2[2] = //blau */ if (aktuellerPixelX > startPixelBreite & aktuellerPixelX< endpixelBreite) { if pixelfarbe[0] = 102 & pixelfarbe[1] = 102 & pixelfabre [2] = 102 //grau { prozent = 60 neuerpixel[0] = (pixelfarbebild1[0]*prozent-100*pixelfarbebild1[0]+100*pixelfarbebild2[0])/prozent //rot neuerpixel[1] = (pixelfarbebild1[1]*prozent-100*pixelfarbebild1[1]+100*pixelfarbebild2[1])/prozent //grün neuerpixel[2] = (pixelfarbebild1[2]*prozent-100*pixelfarbebild1[2]+100*pixelfarbebild2[2])/prozent //blau } else if pixelfarbe[0] = 237 & pixelfarbe[1] = 136 & pixelfabre [2] = 196 //pink { prozent = 70 neuerpixel[0] = (pixelfarbebild1[0]*prozent-100*pixelfarbebild1[0]+100*pixelfarbebild2[0])/prozent //rot neuerpixel[1] = (pixelfarbebild1[1]*prozent-100*pixelfarbebild1[1]+100*pixelfarbebild2[1])/prozent //grün neuerpixel[2] = (pixelfarbebild1[2]*prozent-100*pixelfarbebild1[2]+100*pixelfarbebild2[2])/prozent //blau } else if pixelfarbe[0] = 175 & pixelfarbe[1] = 167 & pixelfabre [2] = 172 //hellgrau { prozent = 67 neuerpixel[0] = (pixelfarbebild1[0]*prozent-100*pixelfarbebild1[0]+100*pixelfarbebild2[0])/prozent //rot neuerpixel[1] = (pixelfarbebild1[1]*prozent-100*pixelfarbebild1[1]+100*pixelfarbebild2[1])/prozent //grün neuerpixel[2] = (pixelfarbebild1[2]*prozent-100*pixelfarbebild1[2]+100*pixelfarbebild2[2])/prozent //blau } else { neuerpixel[0] = pixelfarbebild2[0] //rot neuerpixel[1] = pixelfarbebild2[1] //grün neuerpixel[2] = pixelfarbebild2[2] //blau } //pixel in bild schreiben } else{ neuerpixel[0] = pixelfarbebild2[0] //rot neuerpixel[1] = pixelfarbebild2[1] //grün neuerpixel[2] = pixelfarbebild2[2] //blau } aktuellerPixelX++; //ENDE schleife für pixel pixelreihe //ENDE: Schleife für pixelzeile //ausgabe } 44 Answers
You can/should use "pixel regions" to export/import layers to/from python arrays. A script of mine uses this to transfer Gimp's pixels into a numpy array:
# Returns NP array (N,bpp) (single vector of triplets) def channelData(layer): w,h=layer.width,layer.height region=layer.get_pixel_rgn(0, 0, w,h) pixChars=region[:,:] bpp=region.bpp return np.frombuffer(pixChars,dtype=np.uint8).reshape(w,h,bpp) This is Gimp 2.8 code, might need some changes to support higher bit depths in 2.10.
In the opposite direction:
def createResultLayer(image,name,result): rlBytes=np.uint8(result).tobytes(); rl=gimp.Layer(image,name,image.width,image.height, image.active_layer.type,100,NORMAL_MODE) region=rl.get_pixel_rgn(0, 0, rl.width,rl.height,True) region[:,:]=rlBytes image.add_layer(rl,0) gimp.displays_flush() You can of course drop the numpy part, but if you can express your problem as global array ops things can be very fast. On Windows (or using a flatpak version on Linux), you have to add numpy to the Python runtime used by Gimp. See here for some hints. You'll find the full script here, that can also be used as an example of how to get at the image and layer.
See here for the Python-specific API documentation.
1In GIMP, check the gimp_drawable_get_pixel and gimp_drawable_set_pixel procedures. You can find all the procedures you can use in a python plug-in in the Filters -> Python Fu -> Console.
A very basic code, just to give you an idea, may be:
color_to_edit = (102, 102, 102) #or whatever color you wish to edit, this is an RGB value without alpha channel new_color = (200, 200, 200) #the new color for i in range(x_size): for j in range(y_size): num_channels, pixel = pdb.gimp_drawable_get_pixel(drawable, i, j) if all([p == q for p, q in zip(pixel, color_to_edit)]): pdb.gimp_drawable_set_pixel(drawable, i, j, 3, new_color) pdb.gimp_displays_flush() #this will update the image. Here drawable should be a gimp layer with your image.
A completely different answer, that avoids extracting the pixels from Gimp
So we have the "image" layer (where you color pixels) and the "map" layer (where a given color you indicates which pixels should be colored). Then:
- Do a color selection of the color on the "map" layer (
gimp_by_color_select(maplayer,...)) - Using that selection (which is global in the image and so applies to any layer), color the pixels on the image layer (bucket-fill selection, for a uniform color:
gimp_edit_bucket_fill(imagelayer,...)). - For more complicated color schemes, you can paint a 3rd layer, insert it below the "image" layer, and delete the selected pixels to make it visible through, then merge the image layer on it.
All this is done with Gimp operators, and is very fast. It is also usable as manual procedure, so you can try it in Gimp first without writing a single line of code.
In matlab / octave this is very straightforward. No need for gimp, and integrates well with C++ if you absolutely must have c++ code integration. E.g., say you want to change Image2 pixels to R: 50, G: 60, B:70, whenever Image1 has pixels R:10, G: 20, B:30. Then:
% Alle kommentierure im lingula obfuscatis fur demonstraru how rude it looks Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine R1 = Im1(:,:,1); R2 = Im2(:,:,1); % selectu 'red' layeru piripitsi G1 = Im1(:,:,2); G2 = Im2(:,:,2); % selectu 'green' layeru piripitsi B1 = Im1(:,:,3); B2 = Im2(:,:,3); % selectu 'blue' layeru piripitsi Mask = (R1 == 10) & (G1 == 20) & (B1 == 30); % криеит маск фром чаннелз R2(Mask) = 50; % πουτ 50 γουεαρ Mask ηζ True! G2(Mask) = 60; % πουτ 60 γουεαρ Mask ηζ True! B2(Mask) = 70; % πουτ 70 γουεαρ Mask ηζ True! NewIm2 = cat(3, R2, G2, B2); % Sukasumeseleba! Habibi chan! Uleleleleleeeeeeeh!!!!! You can read and compare images similarly in python using scipy.imread, numpy, etc if you prefer python over matlab. No need for gimp.
PS. As you may have realised from my sarcastic code comments, please consider writing code exclusively in English when asking an international audience such as SO. It's very frustrating and tiresome to read such 'mixed' code and therefore it comes across as rude and inconsiderate; (and this holds true even for someone like me personally, despite the fact that I happen to speak a reasonable amount of German and English is not my native language.). Not to mention that you risk needlessly limiting your audience to only German speakers by doing so!