skip to Main Content

I need to apply crystallized pixels filter to an image via some API or library. This effect should look like this:

image_example

So this is not the usual pixel effect, the pixels are not square shaped.

Is there any API I can use? I have been looking for this but I am a bit lost.

2

Answers


  1. Oops, I just noticed you tagged with PHP not Python – sorry! I’ll leave it for now as reference and may do a PHP version another day.

    I had a quick attempt at this and it works well enough:

    #!/usr/bin/env python3
    
    import numpy
    import random
    import math
    import sys
    from PIL import Image
    
    def crystallize(im, cnt):
        # Make output image same size
        res = np.zeros_like(im)
        h, w = im.shape[:2]
        # Generate some randomly placed crystal centres
        nx = np.random.randint(0,w,cnt,dtype=np.uint16)
        ny = np.random.randint(0,h,cnt,dtype=np.uint16)
        # Pick up colours at those locations from source image
        sRGB = []
        for i in range(cnt):
            sRGB.append(im[ny[i],nx[i]])
    
        # Iterate over image
        for y in range(h):
            for x in range(w):
                # Find nearest crystal centre...
                dmin = sys.float_info.max
                for i in range(cnt):
                    d = (y-ny[i])*(y-ny[i]) + (x-nx[i])*(x-nx[i])
                    if d < dmin:
                        dmin = d
                        j = i
                # ... and copy colour of original image to result
                res[y,x,:] = sRGB[j]
        return res
    
    # Open image, crystallize and save
    im  = Image.open('duck.jpg')
    res = crystallize(np.array(im),200)
    Image.fromarray(res).save('result.png')
    

    It turns this:

    enter image description here

    into this:

    enter image description here

    or this if you go for 500 crystals:

    enter image description here


    The speed can probably be improved by reducing to 256 colours and a palletised image, finding the nearest colour for each and then simply looking them up in a LUT. Maybe a job for a rainy day…


    Keywords: Python, voronoi, crystal, crystallize, Photoshop, filter, image, image processing, Numpy, PIL, Pillow.

    Login or Signup to reply.
  2. Here’s how to apply Crystallize filter with Photoshop api in Python, taken from example https://github.com/lohriialo/photoshop-scripting-python/blob/master/EmbossAction.py

    from win32com.client import Dispatch, GetActiveObject
    
    app = GetActiveObject("Photoshop.Application")
    fileName = "C:GithubTest.psd"
    docRef = app.Open(fileName)
    
    docRef.ActiveLayer = docRef.ArtLayers.Item(1)
    
    def applyCrystallize(cellSize):
        cellSizeID = app.CharIDToTypeID("ClSz")
        eventCrystallizeID = app.CharIDToTypeID("Crst")
        filterDescriptor = Dispatch('Photoshop.ActionDescriptor')
        filterDescriptor.PutInteger(cellSizeID, cellSize)
        app.ExecuteAction(eventCrystallizeID, filterDescriptor)
    
    applyCrystallize(25)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search