Pixel Art.PY

Pixel Art.PY
64x64 Lego Pixelation of 21 by Adele

I loved playing with Legos as a kid and I recently wanted to try them out again. One of the sets that caught my eye was an image remade with Legos

https://www.lego.com/en-us/product/jim-lee-batman-collection-31205

I had recently seen a video where they paired NFC tags with album covers  to play the album on nearby speakers.  I thought it would be cool to replicate this idea for my favorite albums but use a pixelated covers made of Legos.  After a little research I found an online marketplace for Legos where I could purchase the 1x1 bricks I needed.  They cost less than $.01 / piece so I ordered ~5000 pieces of 20 different colors

I then entered the colors, color codes, and quantities into an excel sheet

List of Lego Colors with Color Codes

I wanted to start with one of my favorite albums, 21 by Adele

21 by Adele

Next, I needed to turn this image into something I could build with my Legos.  This would require two steps.  First I would need to convert the image into the Lego colors I had and second I needed to pixelate the image.  To achieve the first step I would look at each pixel and convert it to the nearest Lego color.  After implementing this using the Pillow library, I found that using all 20 colors didn't produce the results I was looking for

21 by Adele Using 20 Colors

The background of the original album is grey but depending on the shade of grey sometimes sometimes the program found brown was the closer color.  To solve this I decided to reduce the number of colors I would use.  I wasn't sure how many colors would produce the best results so I had the program randomly choose either 4, 8, or 16 colors and then repeated the process several time so I would have many options to choose from

#Set Variables
Image_Name = 'Adele'
Sample_Folder_Name = Image_Name + '_Sample'
Save_Name_Orginal = Image_Name + "_Original" + ".png"
Save_Name_Slice =  Image_Name + "-%s.png"
Sample_Name = Sample_Folder_Name + "-%s.png"
k = 1 #Slice Number
Dir_Name = Image_Name

#Create Directory
try:
    # Create target Directory
    os.mkdir(Dir_Name)
    os.mkdir(Dir_Name + "//" + Sample_Folder_Name)
    print("Directory " , Dir_Name ,  " Created ")
except FileExistsError:
    print("Directory " , Dir_Name ,  " already exists")

##########################################################################################
#Import Image
im=Image.open(Path)

for t in range(0,100):
    img = im
    Color_Option = ['4', '8', '16']
    Num_Colors = numpy.random.choice(Color_Option, size=1)
    Num_Colors = int(Num_Colors[0])

    df = pd.read_csv(Path)
    df = df['RGB']

    df = df.str.split(",", expand = True)
    df = df.reset_index(drop = True)
    df = df.drop(3,1)

    df_palette = df.sample(Num_Colors)
    list_palette = df_palette.values.tolist()

    x = ""
    for i in list_palette:
        x += " ".join(str(j) for j in i) + " "

    x = x.split(" ")

    while("" in x) :
        x.remove("")

    for i in range(0, len(x)):
        x[i] = int(x[i])

    palette = x
    p_img = Image.new('P', (16, 16))
    y = 256 / Num_Colors
    y = int(y)

    p_img.putpalette(palette * y)#The 16 is 256 / # of palette colors
    conv = img.quantize(palette=p_img, dither=0)

    try:
        conv.save(os.path.join(Path,"%s" % Image_Name ,Sample_Folder_Name, Save_Name_Slice % t))
    except:
        pass
Python Code to Change the Pixel Color of the Album

This gave me some fun results.  I now had the album in the same colors as my Legos

The next step was to pixelate the photos.  I found some 32x32 base plates I would attach the Legos to so I decided to go with 64x64 pixels and use four plates

    #Pixelate Image
    img = conv
    img = img.resize((64,64),Image.BILINEAR)
    #resize
    o_size = (1000,1000) #output size
    img = img.resize(o_size,Image.NEAREST)
    img.save(os.path.join(Path,"%s" % Image_Name ,Sample_Folder_Name, Sample_Name % t))
    t +=1
Python Code Converting Image Into 64x64 Pixels

I decided to choose the most accurate color option (Show Left Below) for this project but down the line I may go down a less photo realistic palette

I now had a 64x64 pixel album cover in colors I also had in Legos.  The next step was to separate the image into pieces to make it easier to read.  I decided to go with 16 16x16 pixel images

###########Slice Image into 16 / 16 pixel###########
#Import Image
img = Image.open('Path')
imgwidth, imgheight = img.size
height = imgheight / 4
width = imgwidth / 4
for i in range(0,imgheight,int(height)):
    for j in range(0,imgwidth,int(width)):
        box = (j, i, j+width, i+height)
        a = img.crop(box)
        a = a.resize(o_size,Image.NEAREST)
        try:
            a.save(os.path.join(Path,"%s" % Image_Name,Save_Name_Slice % k))
        except:
            pass
        k +=1
Python Code to Split Photo Into 16 Equal Pieces

I could now get started recreating the album cover

1/16 Complete
4/16 Complete
16/16 Complete

Lastly to be able to tap my phone on the album cover and play the album on speakers in the room I purchased some NFC (Near Field Communication) tags. I then used Apple's App Shortcuts to link the tag to the album.  More information about that process can be found here https://practicalhomekit.blogspot.com/2021/03/automating-listening-to-vinyl-records.html

NFC Tag: https://bluefletch.com/near-field-communication-reading-tags-with-android/