Map pixels to a grid of faces
Here is the Add-On: https://github.com/benkl/pixeler


  
  
  I will try to make it a plugin but for now this should help you. Open
  the source image in blender and replace the "test_file =" image
  variable (then run with open system console to see the progress). It
  will create a set of planes colored with the pixel values. You can
  then switch to edit mode and "Remove Doubles" to make it a consistent
  mesh (or seperate by loose/materials). It will slow down with bigger
  images (64*64 is quite fast - 1000*1000 takes a while). As a bonus
  pixels with alpha 0 will be skipped - so you can recreate icons eg (i
  tested single frame jpg and png). I am a designer and code is probably
  terrible - but it works  (feel free to improve it).

#pixeler v0.1 by BK for Blender 2.79 21/01/2018

import bpy

# Set Data Path
D = bpy.data

# Set File Name
test_file = 'blender.png'

# Set img
img = D.images[test_file]

# Get and set image width and height
w = img.size[0]
h = img.size[1]
tfac = img.pixels[:]

# Set basemesh
bpy.ops.mesh.primitive_plane_add(location=(-2.0, -2.0, 0.0))
basemesh = bpy.context.object
dmat = bpy.data.materials.new(name="origin")
basemesh.data.materials.append(dmat)

#Create Grid from Image
z = 0
y = 0
for index in range(0,h):
    x = 0   
    for index in range(0,w):
        x = x+1              

        # Get pixel position in flat array
        colar = (x+(y*w))*4

        # Set color values at current Pixel
        r = tfac[colar-4]
        g = tfac[colar-3]
        b = tfac[colar-2]

        # Alpha Check
        if tfac[colar-1]&gt;0:

            # Add object at Pixel Location
            # bpy.ops.mesh.primitive_plane_add(location=(x*2, y*2, z))
            basemeshi = basemesh.copy()
            basemeshi.data = basemesh.data.copy()
            basemeshi.location.x = x*2
            basemeshi.location.y = y*2                
            bpy.context.scene.objects.link(basemeshi)

            # Get material
            matname = "Mat" + str(r) + str(g) + str(b)
            mat = bpy.data.materials.get(matname)
            if mat is None:

                # create material
                mat = bpy.data.materials.new(name=matname)
                mat.use_nodes = True
                prinode = mat.node_tree.nodes.new(type = "ShaderNodeBsdfPrincipled")
                dif = mat.node_tree.nodes["Diffuse BSDF"]
                outshad = mat.node_tree.nodes["Material Output"]
                mat.node_tree.nodes.remove(dif)
                mat.node_tree.links.new(prinode.outputs[0], outshad.inputs[0])
                #rgb = mat.node_tree.nodes.new(type = "ShaderNodeRGB")

                # PBR Color
                prin = mat.node_tree.nodes["Principled BSDF"]
                prin.inputs[0].default_value = [r, g, b, 1]
                prin.inputs[7].default_value = 0.6

                # Set editor color from pixel value                          
                bpy.data.materials[matname].diffuse_color = (r, g, b)

            # assign to 1st material slot
            basemeshi.data.materials[0] = mat            

            # Join newly creatd meshes
            basemeshi.select = True
            bpy.context.scene.objects.active = basemeshi
            basemesh.select = False                   

            # Print Pixel placement confirmation
            print("Placed object @ x " + str(x) + " y " + str(y))

    # Join line
    bpy.ops.object.join()

    # Incerement y last    
    y = y+1
    #bpy.ops.object.select_all(action='DESELECT')

bpy.context.scene.update()
print("pixels to planes is done")