简体   繁体   English

gimp python - 如何更改像素颜色?

[英]gimp python - how to change pixel color?

I would like to load 2 jpg images with Gimp Python.我想用 Gimp Python 加载 2 张 jpg 图像。 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.如果图 2 中的像素具有一定的 rgb 值,则图 1 中的像素应着色。 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?我不确定 gimp python 是否可以做到这一切?

Primarily I search the commands:我主要搜索命令:
- Load a picture - 加载图片
- User input - 用户输入
- Load pixel RGB value - 加载像素RGB值
- Change pixel RGB value - 更改像素 RGB 值
- Save image - 保存图片

Many thanks in advance提前谢谢了

I first tried c ++, but handling pictures is not that easy.我第一次尝试c++,但是处理图片没那么容易。 My teacher advised me to gimp.我的老师建议我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

}

You can/should use "pixel regions" to export/import layers to/from python arrays.您可以/应该使用“像素区域”向/从python数组导出/导入图层。 A script of mine uses this to transfer Gimp's pixels into a numpy array:我的一个脚本使用它来将 Gimp 的像素传输到一个 numpy 数组中:

# 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.这是 Gimp 2.8 代码,可能需要进行一些更改以支持 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.您当然可以删除 numpy 部分,但是如果您可以将问题表达为全局数组操作,事情会非常快。 On Windows (or using a flatpak version on Linux), you have to add numpy to the Python runtime used by Gimp.在 Windows 上(或在 Linux 上使用 flatpak 版本),您必须将 numpy 添加到 Gimp 使用的 Python 运行时。 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.有关 Python 特定的 API 文档,请参见此处

In GIMP, check the gimp_drawable_get_pixel and gimp_drawable_set_pixel procedures.在 GIMP 中,检查gimp_drawable_get_pixelgimp_drawable_set_pixel程序。 You can find all the procedures you can use in a python plug-in in the Filters -> Python Fu -> Console.您可以在过滤器 -> Python Fu -> 控制台中找到您可以在 Python 插件中使用的所有程序。

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.这里drawable应该是带有图像的 gimp 层。

A completely different answer, that avoids extracting the pixels from Gimp一个完全不同的答案,避免从 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,...) )对“地图”图层上的颜色进行颜色选择( 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,...) ).使用该选区(在图像中是全局的,因此适用于任何图层),为图像图层上的像素着色(桶填充选择,对于统一颜色: 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.所有这些都是由 Gimp 操作员完成的,而且速度非常快。 It is also usable as manual procedure, so you can try it in Gimp first without writing a single line of code.它也可用作手动过程,因此您可以先在 Gimp 中试用它,而无需编写任何代码。

In matlab / octave this is very straightforward.在 matlab/octave 中,这非常简单。 No need for gimp, and integrates well with C++ if you absolutely must have c++ code integration.不需要 gimp,如果你绝对必须有 C++ 代码集成,它可以很好地与 C++ 集成。 Eg, say you want to change Image2 pixels to R: 50, G: 60, B:70, whenever Image1 has pixels R:10, G: 20, B:30.例如,假设您想将 Image2 像素更改为 R:50、G:60、B:70,只要 Image1 具有像素 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.如果您更喜欢 python 而不是 matlab,您可以使用 scipy.imread、numpy 等在 python 中类似地读取和比较图像。 No need for gimp.不需要 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.正如您可能从我讽刺的代码评论中意识到的那样,在询问诸如 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!更不用说这样做可能会不必要地将听众限制为只会说德语的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM