If, for example, you want to multiply all pixels in the red channel by 1.2, and all the green pixels by 0.9, you have several options....
Split the image into Red, Green and Blue channels, upscale the Red channel and recombine:
from PIL import Image
im = Image.open('image.jpg').convert('RGB')
# Split into 3 channels
r, g, b = im.split()
# Increase Reds
r = r.point(lambda i: i * 1.2)
# Decrease Greens
g = g.point(lambda i: i * 0.9)
# Recombine back to RGB image
result = Image.merge('RGB', (r, g, b))
result.save('result.png')
See "Processing Individual Bands" here.
Or, use a matrix to transform the channels:
from PIL import Image
# Open image
im = Image.open('image.jpg')
# Make transform matrix, to multiply R by 1.1, G by 0.9 and leave B unchanged
# newRed = 1.1*oldRed + 0*oldGreen + 0*oldBlue + constant
# newGreen = 0*oldRed + 0.9*OldGreen + 0*OldBlue + constant
# newBlue = 0*oldRed + 0*OldGreen + 1*OldBlue + constant
Matrix = ( 1.1, 0, 0, 0,
0, 0.9, 0, 0,
0, 0, 1, 0)
# Apply transform and save
im = im.convert("RGB", Matrix)
im.save('result.png')
Or, convert to Numpy array, do some processing and convert back to PIL Image:
from PIL import Image
# Open image
im = Image.open('image.jpg')
# Make into Numpy array of floats
na = np.array(im).astype(np.float)
# Multiply all red values by 1.1
na[...,0] *= 1.1
# Reduce green values
na[...,1] *= 0.9
# You may want to use "np.clip()" here to ensure you don't exceed 255
# Convert Numpy array back to PIL Image and save
pi = Image.fromarray(na.astype(np.uint8))
pi.save('result.png')
This option has the added benefit that the Numpy arrays can be intermixed and processed with OpenCV, scikit-image, vips, wand and other libraries to get MUCH more sophisticated processing done - morphology, granulometry, video processing, SIFT, object tracking...