Exemplo n.º 1
0
def get_jpeg_or_png_image_file(item,
                               collection,
                               size,
                               strip_metadata,
                               apply_transforms=False,
                               filename=''):
    '''
    returns a filename with a jpeg or png of the image associated with item, writing a new copy of the image if necessary
    '''
    if not filename:
        filename = collection.get_path(item)
    src_filename = filename
    icopy = None

    def get_processed_copy(icopy):
        if icopy is not None:
            return icopy
        icopy = baseobjects.Item(filename)
        icopy.meta = item.meta.copy()
        if not load_image(icopy,
                          None,
                          lambda: True,
                          apply_transforms=apply_transforms,
                          itemfile=src_filename):
            return None, None
        if 'Orientation' in icopy.meta:
            del icopy.meta['Orientation']
        if 'ImageTransforms' in icopy.meta:
            del icopy.meta['ImageTransforms']
        return icopy

    def write_processed_image(icopy):
        import tempfile
        h, filename = tempfile.mkstemp(
            '.jpg',
            os.path.splitext(os.path.split(src_filename)[1])[0])
        icopy.image.save(filename, quality=95)
        if not strip_metadata:
            metadata.copy_metadata(icopy.meta, src_filename, filename)
        return h, filename

    if size:
        if isinstance(size, str):
            size = tuple(int(dim) for dim in size.split('x'))
        if isinstance(size, int):
            size = (size, size)
        if len(size) > 0 and size[0] > 0 and size[1] > 0:
            icopy = get_processed_copy(icopy)
            icopy.image.thumbnail(size, Image.ANTIALIAS)
    if io.get_mime_type(filename) not in ['image/jpeg', 'image/png']:
        icopy = get_processed_copy(icopy)
    if strip_metadata:
        icopy = get_processed_copy(icopy)
    if apply_transforms and 'ImageTransforms' in item.meta:
        icopy = get_processed_copy(icopy)
    if icopy is not None:
        h, filename = write_processed_image(icopy)
    return filename  ##todo: potentially insecure because the reference to the file handle gets dropped
Exemplo n.º 2
0
def get_jpeg_or_png_image_file(item,collection,size,strip_metadata,apply_transforms=False,filename=''):
    '''
    returns a filename with a jpeg or png of the image associated with item, writing a new copy of the image if necessary
    '''
    if not filename:
        filename=collection.get_path(item)
    src_filename=filename
    icopy=None

    def get_processed_copy(icopy):
        if icopy is not None:
            return icopy
        icopy = baseobjects.Item(filename)
        icopy.meta = item.meta.copy()
        if not load_image(icopy,None,lambda: True, apply_transforms=apply_transforms,itemfile=src_filename):
            return None,None
        if 'Orientation' in icopy.meta:
            del icopy.meta['Orientation']
        if 'ImageTransforms' in icopy.meta:
            del icopy.meta['ImageTransforms']
        return icopy

    def write_processed_image(icopy):
        import tempfile
        h,filename=tempfile.mkstemp('.jpg',os.path.splitext(os.path.split(src_filename)[1])[0])
        icopy.image.save(filename,quality=95)
        if not strip_metadata:
            metadata.copy_metadata(icopy.meta,src_filename,filename)
        return h,filename

    if size:
        if isinstance(size,str):
            size=tuple(int(dim) for dim in size.split('x'))
        if isinstance(size,int):
            size = (size,size)
        if len(size)>0 and size[0]>0 and size[1]>0:
            icopy = get_processed_copy(icopy)
            icopy.image.thumbnail(size,Image.ANTIALIAS)
    if io.get_mime_type(filename) not in ['image/jpeg','image/png']:
        icopy = get_processed_copy(icopy)
    if strip_metadata:
        icopy = get_processed_copy(icopy)
    if apply_transforms and 'ImageTransforms' in item.meta:
        icopy = get_processed_copy(icopy)
    if icopy is not None:
        h,filename = write_processed_image(icopy)
    return filename ##todo: potentially insecure because the reference to the file handle gets dropped
Exemplo n.º 3
0
def make_thumb(item,
               collection,
               interrupt_fn=None,
               force=False,
               cache=None,
               use_embedded=False,
               write_to_cache=True):
    '''
    create a thumbnail from the original image using either PIL or dcraw
    interrupt_fn = callback that returns False if routine should cancel (not implemented)
    force = True if thumbnail should be recreated even if already present
    affects thumb, thumburi members of item
    '''
    itemfile = collection.get_path(item)
    thumb_pb = None
    if cache == None and thumb_factory.has_valid_failed_thumbnail(
            itemfile, int(item.mtime)):
        if not force:
            item.thumb = False
            return False
        print 'Forcing thumbnail creation'
        uri = io.get_uri(itemfile)
        thumb_uri = thumb_factory.lookup(uri, int(item.mtime))
        if write_to_cache and thumb_uri:
            os.remove(thumb_uri)
    if not force and item.thumb == False:
        return False
    delete_thumb(item)
    ##todo: could also try extracting the thumb from the image (essential for raw files)
    ## would not need to make the thumb in that case
    print 'Creating thumbnail for', item.uid, itemfile
    t = time.time()
    try:
        uri = io.get_uri(itemfile)
        mimetype = io.get_mime_type(itemfile)
        thumb_pb = None
        if mimetype.lower().startswith('video'):
            cmd = settings.video_thumbnailer % (itemfile, )
            imdata = os.popen(cmd).read()
            image = Image.open(StringIO.StringIO(imdata))
            image.thumbnail(
                (128, 128),
                Image.ANTIALIAS)  ##TODO: this is INSANELY slow -- find out why
        else:
            try:
                mime = io.get_mime_type(itemfile)
                if use_embedded and load_embedded_thumb(item, collection):
                    thumb_pb = item.thumb
                    image = None
                    print 'Used embedded thumb'
                elif not settings.is_windows and mime in gdk_mime_types:  #todo: this is completely broken on windows
                    thumb_pb = gtk.gdk.pixbuf_new_from_file_at_size(
                        itemfile, 128, 128)
                    thumb_pb = orient_pixbuf(thumb_pb, item.meta)
                    image = None
                    print 'Opened with GDK'
                else:
                    image = Image.open(itemfile)
                    image.thumbnail((128, 128), Image.ANTIALIAS)
                    print 'Opened with PIL'
            except:
                cmd = settings.dcraw_cmd % (itemfile, )
                imdata = os.popen(cmd).read()
                if not imdata or len(imdata) < 100:
                    cmd = settings.dcraw_backup_cmd % (itemfile, )
                    imdata = os.popen(cmd).read()


#                pipe = subprocess.Popen(cmd, shell=True,
#                        stdout=PIPE) ##, close_fds=True
#                print pipe
#                pipe=pipe.stdout
#                print 'pipe opened'
#                imdata=pipe.read()
#                print 'pipe read'
                p = ImageFile.Parser()
                p.feed(imdata)
                image = p.close()
                image.thumbnail((128, 128), Image.ANTIALIAS)
                image = orient_image(image, item.meta)
                print 'Opened with DCRAW'
        if image is not None:
            thumb_pb = image_to_pixbuf(image)
        if thumb_pb is None:
            raise TypeError
    except:
        item.thumb = False
        item.thumburi = None
        if write_to_cache and cache == None:
            thumb_factory.create_failed_thumbnail(itemfile, int(item.mtime))
        print 'Error creating thumbnail for', item
        import sys
        import traceback
        tb_text = traceback.format_exc(sys.exc_info()[2])
        print tb_text
        return False
    width = thumb_pb.get_width()
    height = thumb_pb.get_height()
    uri = io.get_uri(itemfile)
    #save the new thumbnail
    try:
        if write_to_cache:
            if cache == None:
                thumb_factory.save_thumbnail(thumb_pb, uri, int(item.mtime))
                item.thumburi = thumb_factory.lookup(uri, int(item.mtime))
            else:
                if not os.path.exists(cache):
                    os.makedirs(cache)
                item.thumburi = os.path.join(
                    cache, muuid(item.uid + str(int(item.mtime)))) + '.png'
                thumb_pb.save(item.thumburi, "png")
            print 'cached at', item.thumburi
    except:
        print 'Error caching thumbnail for', item
        import sys
        import traceback
        tb_text = traceback.format_exc(sys.exc_info()[2])
        print tb_text
        item.thumb = False
        item.thumburi = None
        if write_to_cache and cache == None:
            thumb_factory.create_failed_thumbnail(itemfile, int(item.mtime))
        return False
    item.thumb = thumb_pb
    cache_thumb_in_memory(item)
    return True
Exemplo n.º 4
0
def load_image(item,
               collection,
               interrupt_fn,
               draft_mode=False,
               apply_transforms=True,
               itemfile=None):
    '''
    load a PIL image and store it in item.image
    if transform_handlers are specified and the image has tranforms they will be applied
    '''
    if itemfile is None:
        itemfile = collection.get_path(item)
    mimetype = io.get_mime_type(itemfile)
    oriented = False
    try:
        ##todo: load by mimetype (after porting to gio)
        #        non-parsed version
        if 'original_image' in item.__dict__:
            image = item.original_image.copy()
            oriented = True
        else:
            if not mimetype.startswith('image'):
                print 'No image available for item', item, 'with mimetype', mimetype
                item.image = False
                return False
            print 'Loading Image:', item, mimetype
            if io.get_mime_type(
                    itemfile
            ) in settings.raw_image_types:  ##for extraction with dcraw
                raise TypeError
            image = Image.open(
                itemfile
            )  ## retain this call even in the parsed version to avoid lengthy delays on raw images (since this call trips the exception)
            #        parsed version
            if not draft_mode and image.format == 'JPEG':
                #parser doesn't seem to work correctly on anything but JPEGs
                f = open(itemfile, 'rb')
                imdata = f.read(10000)
                p = ImageFile.Parser()
                while imdata and len(imdata) > 0:
                    p.feed(imdata)
                    if not interrupt_fn():
                        return False
                    imdata = f.read(10000)
                f.close()
                image = p.close()
                print 'Parsed image with PIL'
            else:
                raise TypeError
    except:
        try:
            if mimetype in gdk_mime_types:
                image_pb = gtk.gdk.pixbuf_new_from_file(itemfile)
                image_pb = orient_pixbuf(image_pb, item.meta)
                print image_pb.get_has_alpha()
                print image_pb.get_n_channels()
                print image_pb.get_colorspace()
                oriented = True
                width, height = image_pb.get_width(), image_pb.get_height()
                if image_pb.get_n_channels() >= 3:
                    if image_pb.get_has_alpha():
                        image = Image.fromstring("RGBA", (width, height),
                                                 image_pb.get_pixels())
                    else:
                        image = Image.fromstring("RGB", (width, height),
                                                 image_pb.get_pixels())
                else:
                    print "GDK Parser - Can't handle image with less than 3 channel"
                    raise TypeError
                print 'Parsed image with GDK'
            else:
                if mimetype in settings.raw_image_types:
                    cmd = settings.raw_image_types[mimetype][0] % (itemfile, )
                else:
                    cmd = settings.dcraw_cmd % (itemfile, )
                imdata = os.popen(cmd).read()
                if not imdata or len(imdata) < 100:
                    cmd = settings.dcraw_backup_cmd % (itemfile, )
                    oriented = True
                    imdata = os.popen(cmd).read()
                    if not interrupt_fn():
                        return False
                p = ImageFile.Parser()
                p.feed(imdata)
                image = p.close()
                print 'Parsed image with DCRAW'
        except:
            import sys
            import traceback
            tb_text = traceback.format_exc(sys.exc_info()[2])
            print 'Error Loading Image', item, mimetype
            print tb_text
            item.image = False
            return False
    print item.meta
    if draft_mode:
        image.draft(image.mode,
                    (1024, 1024))  ##todo: pull size from screen resolution
    if not interrupt_fn():
        return
    if oriented:
        item.image = orient_image(image, {})
    else:
        item.image = orient_image(image, item.meta)
    try:
        item.imagergba = 'A' in item.image.getbands()
    except:
        item.imagergba = False
    if item.image:
        if apply_transforms:
            transformer.apply_transforms(item, interrupt_fn)
        cache_image(item)
        return True
    return False
Exemplo n.º 5
0
def make_thumb(item,collection,interrupt_fn=None,force=False,cache=None,use_embedded=False,write_to_cache=True):
    '''
    create a thumbnail from the original image using either PIL or dcraw
    interrupt_fn = callback that returns False if routine should cancel (not implemented)
    force = True if thumbnail should be recreated even if already present
    affects thumb, thumburi members of item
    '''
    itemfile=collection.get_path(item)
    thumb_pb=None
    if cache==None and thumb_factory.has_valid_failed_thumbnail(itemfile,int(item.mtime)):
        if not force:
            item.thumb=False
            return False
        print 'Forcing thumbnail creation'
        uri = io.get_uri(itemfile)
        thumb_uri=thumb_factory.lookup(uri,int(item.mtime))
        if write_to_cache and thumb_uri:
            os.remove(thumb_uri)
    if not force and item.thumb==False:
        return False
    delete_thumb(item)
    ##todo: could also try extracting the thumb from the image (essential for raw files)
    ## would not need to make the thumb in that case
    print 'Creating thumbnail for',item.uid,itemfile
    t=time.time()
    try:
        uri = io.get_uri(itemfile)
        mimetype=io.get_mime_type(itemfile)
        thumb_pb=None
        if mimetype.lower().startswith('video'):
            cmd=settings.video_thumbnailer%(itemfile,)
            imdata=os.popen(cmd).read()
            image=Image.open(StringIO.StringIO(imdata))
            image.thumbnail((128,128),Image.ANTIALIAS) ##TODO: this is INSANELY slow -- find out why
        else:
            try:
                mime=io.get_mime_type(itemfile)
                if use_embedded and load_embedded_thumb(item,collection):
                    thumb_pb = item.thumb
                    image = None
                    print 'Used embedded thumb'
                elif not settings.is_windows and mime in gdk_mime_types: #todo: this is completely broken on windows
                    thumb_pb = gtk.gdk.pixbuf_new_from_file_at_size(itemfile,128,128)
                    thumb_pb = orient_pixbuf(thumb_pb,item.meta)
                    image = None
                    print 'Opened with GDK'
                else:
                    image=Image.open(itemfile)
                    image.thumbnail((128,128),Image.ANTIALIAS)
                    print 'Opened with PIL'
            except:
                cmd=settings.dcraw_cmd%(itemfile,)
                imdata=os.popen(cmd).read()
                if not imdata or len(imdata)<100:
                    cmd=settings.dcraw_backup_cmd%(itemfile,)
                    imdata=os.popen(cmd).read()
#                pipe = subprocess.Popen(cmd, shell=True,
#                        stdout=PIPE) ##, close_fds=True
#                print pipe
#                pipe=pipe.stdout
#                print 'pipe opened'
#                imdata=pipe.read()
#                print 'pipe read'
                p = ImageFile.Parser()
                p.feed(imdata)
                image = p.close()
                image.thumbnail((128,128),Image.ANTIALIAS)
                image=orient_image(image,item.meta)
                print 'Opened with DCRAW'
        if image is not None:
            thumb_pb=image_to_pixbuf(image)
        if thumb_pb is None:
            raise TypeError
    except:
        item.thumb=False
        item.thumburi=None
        if write_to_cache and cache==None:
            thumb_factory.create_failed_thumbnail(itemfile,int(item.mtime))
        print 'Error creating thumbnail for',item
        import sys
        import traceback
        tb_text=traceback.format_exc(sys.exc_info()[2])
        print tb_text
        return False
    width=thumb_pb.get_width()
    height=thumb_pb.get_height()
    uri = io.get_uri(itemfile)
    #save the new thumbnail
    try:
        if write_to_cache:
            if cache==None:
                thumb_factory.save_thumbnail(thumb_pb,uri,int(item.mtime))
                item.thumburi=thumb_factory.lookup(uri,int(item.mtime))
            else:
                if not os.path.exists(cache):
                    os.makedirs(cache)
                item.thumburi=os.path.join(cache,muuid(item.uid+str(int(item.mtime))))+'.png'
                thumb_pb.save(item.thumburi,"png")
            print 'cached at',item.thumburi
    except:
        print 'Error caching thumbnail for',item
        import sys
        import traceback
        tb_text=traceback.format_exc(sys.exc_info()[2])
        print tb_text
        item.thumb=False
        item.thumburi=None
        if write_to_cache and cache==None:
            thumb_factory.create_failed_thumbnail(itemfile,int(item.mtime))
        return False
    item.thumb=thumb_pb
    cache_thumb_in_memory(item)
    return True
Exemplo n.º 6
0
def load_image(item,collection,interrupt_fn,draft_mode=False,apply_transforms=True,itemfile=None):
    '''
    load a PIL image and store it in item.image
    if transform_handlers are specified and the image has tranforms they will be applied
    '''
    if itemfile is None:
        itemfile=collection.get_path(item)
    mimetype=io.get_mime_type(itemfile)
    oriented=False
    try:
        ##todo: load by mimetype (after porting to gio)
#        non-parsed version
        if 'original_image' in item.__dict__:
            image=item.original_image.copy()
            oriented=True
        else:
            if not mimetype.startswith('image'):
                print 'No image available for item',item,'with mimetype',mimetype
                item.image=False
                return False
            print 'Loading Image:',item,mimetype
            if io.get_mime_type(itemfile) in settings.raw_image_types: ##for extraction with dcraw
                raise TypeError
            image=Image.open(itemfile) ## retain this call even in the parsed version to avoid lengthy delays on raw images (since this call trips the exception)
    #        parsed version
            if not draft_mode and image.format=='JPEG':
                #parser doesn't seem to work correctly on anything but JPEGs
                f=open(itemfile,'rb')
                imdata=f.read(10000)
                p = ImageFile.Parser()
                while imdata and len(imdata)>0:
                    p.feed(imdata)
                    if not interrupt_fn():
                        return False
                    imdata=f.read(10000)
                f.close()
                image = p.close()
                print 'Parsed image with PIL'
            else:
                raise TypeError
    except:
        try:
            if mimetype in gdk_mime_types:
                image_pb=gtk.gdk.pixbuf_new_from_file(itemfile)
                image_pb=orient_pixbuf(image_pb,item.meta)
                print image_pb.get_has_alpha()
                print image_pb.get_n_channels()
                print image_pb.get_colorspace()
                oriented=True
                width,height = image_pb.get_width(),image_pb.get_height()
                if image_pb.get_n_channels() >=3:
                    if image_pb.get_has_alpha():
                        image=Image.fromstring("RGBA",(width,height),image_pb.get_pixels() )
                    else:
                        image=Image.fromstring("RGB",(width,height),image_pb.get_pixels() )
                else:
                    print "GDK Parser - Can't handle image with less than 3 channel"
                    raise TypeError
                print 'Parsed image with GDK'
            else:
                if mimetype in settings.raw_image_types:
                    cmd=settings.raw_image_types[mimetype][0]%(itemfile,)
                else:
                    cmd=settings.dcraw_cmd%(itemfile,)
                imdata=os.popen(cmd).read()
                if not imdata or len(imdata)<100:
                    cmd=settings.dcraw_backup_cmd%(itemfile,)
                    oriented=True
                    imdata=os.popen(cmd).read()
                    if not interrupt_fn():
                        return False
                p = ImageFile.Parser()
                p.feed(imdata)
                image = p.close()
                print 'Parsed image with DCRAW'
        except:
            import sys
            import traceback
            tb_text=traceback.format_exc(sys.exc_info()[2])
            print 'Error Loading Image',item,mimetype
            print tb_text
            item.image=False
            return False
    print item.meta
    if draft_mode:
        image.draft(image.mode,(1024,1024)) ##todo: pull size from screen resolution
    if not interrupt_fn():
        return
    if oriented:
        item.image=orient_image(image,{})
    else:
        item.image=orient_image(image,item.meta)
    try:
        item.imagergba='A' in item.image.getbands()
    except:
        item.imagergba=False
    if item.image:
        if apply_transforms:
            transformer.apply_transforms(item,interrupt_fn)
        cache_image(item)
        return True
    return False