gimp python - how to change pixel color?











up vote
1
down vote

favorite












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

}









share|improve this question
























  • Please show the code of what you have tried so far.
    – mbuechmann
    Nov 19 at 18:37










  • Supplement please see above
    – Chris
    Nov 19 at 18:48












  • What have you tried in python?
    – mbuechmann
    Nov 19 at 19:02






  • 1




    If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
    – xenoid
    Nov 19 at 22:32















up vote
1
down vote

favorite












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

}









share|improve this question
























  • Please show the code of what you have tried so far.
    – mbuechmann
    Nov 19 at 18:37










  • Supplement please see above
    – Chris
    Nov 19 at 18:48












  • What have you tried in python?
    – mbuechmann
    Nov 19 at 19:02






  • 1




    If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
    – xenoid
    Nov 19 at 22:32













up vote
1
down vote

favorite









up vote
1
down vote

favorite











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

}









share|improve this question















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

}






python gimp gimpfu






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 18:50

























asked Nov 19 at 18:35









Chris

205




205












  • Please show the code of what you have tried so far.
    – mbuechmann
    Nov 19 at 18:37










  • Supplement please see above
    – Chris
    Nov 19 at 18:48












  • What have you tried in python?
    – mbuechmann
    Nov 19 at 19:02






  • 1




    If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
    – xenoid
    Nov 19 at 22:32


















  • Please show the code of what you have tried so far.
    – mbuechmann
    Nov 19 at 18:37










  • Supplement please see above
    – Chris
    Nov 19 at 18:48












  • What have you tried in python?
    – mbuechmann
    Nov 19 at 19:02






  • 1




    If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
    – xenoid
    Nov 19 at 22:32
















Please show the code of what you have tried so far.
– mbuechmann
Nov 19 at 18:37




Please show the code of what you have tried so far.
– mbuechmann
Nov 19 at 18:37












Supplement please see above
– Chris
Nov 19 at 18:48






Supplement please see above
– Chris
Nov 19 at 18:48














What have you tried in python?
– mbuechmann
Nov 19 at 19:02




What have you tried in python?
– mbuechmann
Nov 19 at 19:02




1




1




If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
– xenoid
Nov 19 at 22:32




If you are just trying to mass-process pictures, you can (should...) avoid Gimp. There are Python libraries to load/save and edit images, see PIL (or its "pillow" fork). ImageMagick also has bindings for Python.
– xenoid
Nov 19 at 22:32












4 Answers
4






active

oldest

votes

















up vote
0
down vote













In 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.






share|improve this answer























  • get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
    – xenoid
    Nov 19 at 21:56


















up vote
0
down vote













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.






share|improve this answer






























    up vote
    0
    down vote













    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.






    share|improve this answer






























      up vote
      0
      down vote













      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 retardata fur demonstraru how rude it looks

      Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine
      R1 = Im1(:,:,1); R2 = Im1(:,:,1); % selectu 'red' layeru piripitsi
      G1 = Im1(:,:,2); G2 = Im1(:,:,2); % selectu 'green' layeru piripitsi
      B1 = Im1(:,:,3); B2 = Im1(:,:,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!






      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380721%2fgimp-python-how-to-change-pixel-color%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        0
        down vote













        In 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.






        share|improve this answer























        • get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
          – xenoid
          Nov 19 at 21:56















        up vote
        0
        down vote













        In 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.






        share|improve this answer























        • get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
          – xenoid
          Nov 19 at 21:56













        up vote
        0
        down vote










        up vote
        0
        down vote









        In 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.






        share|improve this answer














        In 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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 19 at 19:50

























        answered Nov 19 at 19:42









        Valentino

        10415




        10415












        • get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
          – xenoid
          Nov 19 at 21:56


















        • get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
          – xenoid
          Nov 19 at 21:56
















        get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
        – xenoid
        Nov 19 at 21:56




        get_pixel() and set_pixel() are very slow operations. They are OK to sample a color, but not really usable on a full picture.
        – xenoid
        Nov 19 at 21:56












        up vote
        0
        down vote













        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.






        share|improve this answer



























          up vote
          0
          down vote













          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.






          share|improve this answer

























            up vote
            0
            down vote










            up vote
            0
            down vote









            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 19 at 22:28

























            answered Nov 19 at 21:55









            xenoid

            2,4882820




            2,4882820






















                up vote
                0
                down vote













                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.






                share|improve this answer



























                  up vote
                  0
                  down vote













                  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.






                  share|improve this answer

























                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    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.






                    share|improve this answer














                    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.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 19 at 22:29

























                    answered Nov 19 at 22:16









                    xenoid

                    2,4882820




                    2,4882820






















                        up vote
                        0
                        down vote













                        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 retardata fur demonstraru how rude it looks

                        Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine
                        R1 = Im1(:,:,1); R2 = Im1(:,:,1); % selectu 'red' layeru piripitsi
                        G1 = Im1(:,:,2); G2 = Im1(:,:,2); % selectu 'green' layeru piripitsi
                        B1 = Im1(:,:,3); B2 = Im1(:,:,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!






                        share|improve this answer

























                          up vote
                          0
                          down vote













                          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 retardata fur demonstraru how rude it looks

                          Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine
                          R1 = Im1(:,:,1); R2 = Im1(:,:,1); % selectu 'red' layeru piripitsi
                          G1 = Im1(:,:,2); G2 = Im1(:,:,2); % selectu 'green' layeru piripitsi
                          B1 = Im1(:,:,3); B2 = Im1(:,:,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!






                          share|improve this answer























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            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 retardata fur demonstraru how rude it looks

                            Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine
                            R1 = Im1(:,:,1); R2 = Im1(:,:,1); % selectu 'red' layeru piripitsi
                            G1 = Im1(:,:,2); G2 = Im1(:,:,2); % selectu 'green' layeru piripitsi
                            B1 = Im1(:,:,3); B2 = Im1(:,:,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!






                            share|improve this answer












                            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 retardata fur demonstraru how rude it looks

                            Im1 = imread('im1.jpg'); Im2 = imread('im2.jpg'); % readure imagurine
                            R1 = Im1(:,:,1); R2 = Im1(:,:,1); % selectu 'red' layeru piripitsi
                            G1 = Im1(:,:,2); G2 = Im1(:,:,2); % selectu 'green' layeru piripitsi
                            B1 = Im1(:,:,3); B2 = Im1(:,:,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!







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 20 at 1:15









                            Tasos Papastylianou

                            10.7k1931




                            10.7k1931






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380721%2fgimp-python-how-to-change-pixel-color%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                                Alcedinidae

                                RAC Tourist Trophy