# How to shift color values of a single RGB channel

I’m a weaver and textile maker with no prior coding or programming experience. In researching and reading through posts on this and other message boards, I was able to find a lot of useful information, but nothing that I could clearly map on what it is I’m trying to do. I’m hoping someone can steer me in the right direction.

I’m working with a set of 18x18 (324px), 8 bit RGB color PNGs which will ultimately be converted into weave structures. I am interested in implementing a script which will allow me to change the value of all pixels of a particular color channel. I’m seeing a number of posts describing how to change the color values of specific pixels, but little about making global changes to the color channels themselves.

I want to be able to manipulate each color channel separately. For example, I'd like to be able to edit all RED pixels in an image such that all R pixel values increase by, say, 2, while pixels containing no R remain unchanged. Additionally, I want to be able to specify a limit, e.g. if the maximum R value in the image is 178, all R pixel values equaling 178 will remain unchanged, while all pixels with R values less than 178 will increase in value by 2.

I hope to be able to specify the channel (e.g. RED), amount of change (e.g. 2, 1, etc.), type of change (e.g. increase/decrease), and limit (e.g. n = 178, n = 0, n = 255, etc.) as those variables will need to be adjusted to satisfy different color palettes and weave structures.

I've tried achieving this in Photoshop and other graphics editors, but outside of selecting like pixels and adjusting their values manually, I haven't had luck in finding an effective solution for this.   I’m wondering - 1) how feasible this is, 2) what program (e.g. Gimp, ImageMagick, etc.) and/or programming language might provide the most straightforward, expedient solution and 3) if anybody has any tips about how go about writing a script like this, as this is all quite new to me.

I don't have any direct experience doing this so I might be missing an obvious solution or tool. That said, what you describe is in programming terms comparatively easy to achieve. The basic structure of such a custom processing would be:

1. Open the image file and get access to the array of pixels it contains.
2. Iterate over all the pixels and inspect/transform however you want.
3. Write out the resulting modified image in the desired format.

Both Gimp (1, 2) and Photoshop (tutorial) provide scripting or plugins support which will allow you to provide custom logic for step 2 and handle the rest for you. I don't have any experience with either, but from a very quick overview, I recommend that you use Javascript, Python or another scripting language which will be much more accessible as a new programmer than a language like C.

Another option I found outside of an image editor that looks good is the Python Imaging Library. Here is a very relevant other question on SO: https://stackoverflow.com/questions/36468530/changing-pixel-color-value-in-pil

From it, I was able to write the following Python script that does what you asked:

from PIL import Image

img = Image.open("input.png")
pixels = img.load() # create the pixel map

# configuration
channel = 0 # 0 = red, 1 = green, 2 = blue
change_amount = 2 # can be -2 for decrease
limit = 178

for i in range(img.size[0]): # for every pixel (in 2D):
for j in range(img.size[1]):
if pixels[i,j][channel] < limit:
# Only modify pixels below the set limit.
# The following "strange" code is used because Python tuples can't be modified
# directly. The tuple is transformed into a (mutable) list and moved back again
# to a tuple afterwards. You can safely ignore this and concentrate on the
# second line that actually modifies a channel's value.
color = list(pixels[i,j])
# Increase (or decrease for a negative change_amount value) the chosen channel.
color[channel] += change_amount
pixels[i,j] = tuple(color)

img.save("out.png")


This is untested code, but it shows how to translate what you want into code. You already described what you wanted in a very programmer-friendly manner so the translation is almost direct. The sky is the limit then as to what you can do with pixels once you load them in a custom program to manipulate them.