Example #1
0
    class ReflectiveRetrieval:
        def __init__(self, xy, image):
            self.image_mapper = ImageMapper()
            self.image = self.image_mapper.read_file(image).resize(xy)

        def get(self, pixel):
            return self.image_mapper.read_image(
                self.image_mapper.colorize_image(self.image, pixel)
            )
Example #2
0
    class LibraryRetrieval:
        def __init__(self, xy):
            self.image_mapper = ImageMapper()
            self.xy = xy
            self.weight = .9  # decrease for fine tuning color spectrum values

        def load_library(self, library):
            if not isinstance(library, ImageLibrary):
                raise ValueError("library must be an ImageLibrary")
            self.image_library = library
            self.image_library.init()

        def get(self, pixel):
            if not hasattr(self, 'image_library'):
                raise ValueError("no image library has been loaded")

            # retrieve image
            file = self.image_library.next(pixel)
            image = self.image_mapper.read_file(file).resize(self.xy)

            # mask to specific color tone
            image = self.image_mapper.colorize_image(image, pixel, self.weight)

            return self.image_mapper.read_image(image)
from image_library import ImageRetrievalFactory, ImageLibrary
import os
import shutil
from image import ImageMapper

test_library = 'test_image_library'
image_mapper = ImageMapper()


def test_init_fails_with_no_library():
    test_subject = ImageLibrary(test_library)
    remove_library()
    try:
        test_subject.init()
        raise RuntimeError("expected ImageLibraryError")
    except ImageLibrary.ImageLibraryError:
        pass


def test_init_fails_with_empty_library():
    test_subject = ImageLibrary(test_library)
    create_library()
    try:
        test_subject.init()
        raise RuntimeError("expected ImageLibraryError")
    except ImageLibrary.ImageLibraryError:
        pass
    remove_library()


def test_init_fails_with_empty_subfolders():
Example #4
0
from image import ImageMapper
from PIL import Image
import collections

testSubject = ImageMapper()

def test_read_file():
    result = testSubject.read_file('test/data/nature.jpg')
    assert isinstance(result, Image.Image)

def test_read_pixels():
    result = testSubject.read_pixels('test/data/nature.jpg')
    assert isinstance(result, collections.Sequence)  # image map
    assert isinstance(result[0], collections.Sequence)  # col map
    assert isinstance(result[0][0], collections.Sequence)  # pixel

def test_read_image_equates_to_read_pixels():
    result = testSubject.read_image(testSubject.read_file('test/data/nature.jpg'))
    assert isinstance(result, collections.Sequence)  # image map
    assert isinstance(result[0], collections.Sequence)  # col map
    assert isinstance(result[0][0], collections.Sequence)  # pixel

def test_write_pixels():
    file = 'test/data/out/image-mapper.jpg'
    colors = [(255,0,0),(0,255,0),(0,0,255)]
    colorsX = 30
    y = 100
    pixels = []
    for c in colors:
        for i in range(0, colorsX):
            col = []
Example #5
0
 def __init__(self, library_name=LIBRARY_NAME):
     self.library_path = os.path.dirname(os.path.realpath(__file__)) \
         + '/' + library_name
     self.color_mapper = ImageLibrary.ColorMapper()
     self.image_mapper = ImageMapper()
Example #6
0
class ImageLibrary:
    LIBRARY_NAME = 'image_library'

    def __init__(self, library_name=LIBRARY_NAME):
        self.library_path = os.path.dirname(os.path.realpath(__file__)) \
            + '/' + library_name
        self.color_mapper = ImageLibrary.ColorMapper()
        self.image_mapper = ImageMapper()

    def init(self):
        self.library_files = {}

        try:
            library_dirs = os.listdir(self.library_path)
        except FileNotFoundError:
            raise self.ImageLibraryError("No image library found at {0}"
                .format(self.library_path))
        for color in self.ColorMapper.COLOR_SPECTRUM:
            if not color in library_dirs:
                raise self.ImageLibraryError(
                    "Local image library is missing directory for color {0}"
                    .format(color))

            images = os.listdir(self.library_path + '/' + color)

            if not len(images) > 0:
                raise self.ImageLibraryError(
                    "Local image library has no images under directory {0}"
                    .format(color))

            self.library_files[color] = [0, images]

    def create(self):
        if not os.path.isdir(self.library_path):
            os.mkdir(self.library_path)
        for color in self.ColorMapper.COLOR_SPECTRUM:
            color_dir = self.library_path + '/' + color
            if not os.path.isdir(color_dir):
                os.mkdir(color_dir)

    def next(self, pixel):
        if not hasattr(self, 'library_files'):
            raise self.ImageLibraryError("This object has not been initialized")

        color = self.color_mapper.name(pixel)

        color_list = self.library_files[color]
        index = color_list[0]

        # we have reached the end of the image files for this color
        if index >= len(color_list[1]):
            index = 0

        # increment for next retrieval
        self.library_files[color][0] = index + 1

        return "{0}/{1}/{2}".format(
                self.library_path,
                color,
                self.library_files[color][1][index]
            )

    def add_file(self, color, file, size):
        destination_file = os.path.basename(file)
        if os.path.exists("{0}/{1}/{2}"
            .format(self.library_path, color, destination_file)):
            destination_file = "{0}_{1}".format(time.time(), destination_file)

        # add scaled file
        image = self.image_mapper.read_file(file)
        image.thumbnail((size, size))
        image.save("{0}/{1}/{2}"
            .format(self.library_path, color, destination_file))

        # remove original
        os.remove(file)

    ## for reporting out library state issues
    class ImageLibraryError(Exception):
        def __init__(self, message):
            self.message = message

        def __str__(self):
            return repr(self.message)

    ## maps from pixels to library colors
    class ColorMapper:
        # RBG color wheel averages tuned from https://rgbcolorcode.com/
        COLOR_SPECTRUM = {
            'blue': PixelFactory.parse((57, 85, 224)),
            'brown': PixelFactory.parse((152, 118, 84)),
            'gray': PixelFactory.parse((128, 128, 128)),
            'green': PixelFactory.parse((27, 158, 0)),
            'lilac': PixelFactory.parse((182, 60, 201)),
            'orange': PixelFactory.parse((237, 122, 46)),
            'pink': PixelFactory.parse((217, 65, 176)),
            'red': PixelFactory.parse((180, 0, 0)),
            'turquoise': PixelFactory.parse((59, 207, 205)),
            'white': PixelFactory.parse((235, 236, 237)),
            'yellow': PixelFactory.parse((255, 213, 0))
        }

        def name(self, pixel):
            closest_distance = PixelFactory.MAX_PIXEL_DISTANCE
            result = 'white'
            pixel_object = PixelFactory.parse(pixel)

            for name, color in self.COLOR_SPECTRUM.items():
                color_distance = pixel_object.distance(color)
                if color_distance < closest_distance:
                    closest_distance = color_distance
                    result = name

            return result

    # provide public visibility without knowledge of internals
    COLORS = ColorMapper.COLOR_SPECTRUM.keys()
Example #7
0
 def __init__(self, xy):
     self.image_mapper = ImageMapper()
     self.xy = xy
     self.weight = .9  # decrease for fine tuning color spectrum values
Example #8
0
 def __init__(self, xy, image):
     self.image_mapper = ImageMapper()
     self.image = self.image_mapper.read_file(image).resize(xy)
Example #9
0
                        help='Mosaic thumbnail tile X dimension')
arg_parser.add_argument('-y',
                        dest='y',
                        type=int,
                        help='Mosaic thumbnail tile Y dimension')
arg_parser.add_argument('-o',
                        dest='output_file',
                        type=str,
                        required=True,
                        help='Mosaic output image name')

args = arg_parser.parse_args()

# mosaic creation constructs
dimensions = (args.x or args.thumb_size, args.y or args.thumb_size)
image_mapper = ImageMapper()
mosaic_builder = Mosaic()
pixel_analyzer = PixelAnalyzer()
image_retriever = ImageRetrievalFactory.construct(args.source_type, dimensions,
                                                  args.input_file)
image_library = ImageLibrary()

print("Parsing source image...")
mosaic = mosaic_builder.tile(image_mapper.read_pixels(args.input_file),
                             dimensions)

if args.source_type == ImageRetrievalFactory.RETRIEVE_LIBRARY:
    print("Loading image library...")
    image_retriever.load_library(image_library)

print("Generating photomosaic...")