Transform an image to a bitmap

22,562

Solution 1

Check this one out:

from PIL import Image
import numpy as np

img = Image.open('road.jpg')
ary = np.array(img)

# Split the three channels
r,g,b = np.split(ary,3,axis=2)
r=r.reshape(-1)
g=r.reshape(-1)
b=r.reshape(-1)

# Standard RGB to grayscale 
bitmap = list(map(lambda x: 0.299*x[0]+0.587*x[1]+0.114*x[2], 
zip(r,g,b)))
bitmap = np.array(bitmap).reshape([ary.shape[0], ary.shape[1]])
bitmap = np.dot((bitmap > 128).astype(float),255)
im = Image.fromarray(bitmap.astype(np.uint8))
im.save('road.bmp')

The program takes an rgb image and converts it in a numpy array. It then splits it in 3 vectors, one for each channel. I uses the color vectors to create a gray vector. After that it comperes elements with 128, if lower than writes 0(black) else is 255. Next step is reshape and save.

road.jpg road.bmp

Solution 2

You can use pillow

from PIL import Image

img = Image.open("haha.jpg")
img = img.tobitmap()

Solution 3

It takes three steps to do it. First convert original image to a list of pixels. Second change every pixel to either black(0,0,0) or white(255,255,255). Third convert the list back to image and save it.

code:

from PIL import Image

threshold = 10

# convert image to a list of pixels
img = Image.open('letter.jpg')
pixels = list(img.getdata())

# convert data list to contain only black or white
newPixels = []
for pixel in pixels:
    # if looks like black, convert to black
    if pixel[0] <= threshold:
        newPixel = (0, 0, 0)
    # if looks like white, convert to white
    else:
        newPixel = (255, 255, 255)
    newPixels.append(newPixel)

# create a image and put data into it
newImg = Image.new(img.mode, img.size)
newImg.putdata(newPixels)
newImg.save('new-letter.jpg')

threshold is what decides a pixel being black or white, as you can see it the code. Threshold of 50 looks like this enter image description here, threshold of 30 looks like this enter image description here, threshold of 10 looks like this enter image description here, if you tune it down to 5, the output starts to lose pixels: enter image description here.

Share:
22,562
Leonardo Burrone
Author by

Leonardo Burrone

Updated on June 18, 2020

Comments

  • Leonardo Burrone
    Leonardo Burrone almost 4 years

    I'm trying to create like a bitmap for an image of a letter but I'm not having the desired result. It's been a few days that I started working with images. I tried to read the image, create a numpy array of it and save the content in a file. I wrote the code bellow:

    import numpy as np
    from skimage import io
    from skimage.transform import resize
    
    image = io.imread(image_path, as_grey=True)
    image = resize(image, (28, 28), mode='nearest')
    array = np.array(image)
    np.savetxt("file.txt", array, fmt="%d")
    

    I'm trying to use images like in this link bellow:

    Letter "e"

    I was trying to create an array of 0's and 1's. Where the 0's represent the white pixels and the 1's represent the black pixels. Then when I save the result in a file I can see the letter format.

    Can anyone guide me on how to get this result?

    Thank you.