utility functions for handling images requires pillow as you might imagine a mixin for use alongside django core files base file which provides additional features for dealing with images return the width height of an image given an open file or a path set close to true to close the file at the end if it is initially in an open state most of the time pillow only needs a small chunk to parse the image and get the dimensions but with some tiff files pillow needs to parse the whole file ignore zlib complaining on truncated stream just feed more data to parser ticket 19457 ignore pil failing on a too short buffer when reads return less bytes than expected skip and feed more data to the parser ticket 24544 e g runtimeerror could not create decoder object for webp files a different chunksize may work a mixin for use alongside django core files base file which provides additional features for dealing with images return the width height of an image given an open file or a path set close to true to close the file at the end if it is initially in an open state most of the time pillow only needs a small chunk to parse the image and get the dimensions but with some tiff files pillow needs to parse the whole file ignore zlib complaining on truncated stream just feed more data to parser ticket 19457 ignore pil failing on a too short buffer when reads return less bytes than expected skip and feed more data to the parser ticket 24544 e g runtimeerror could not create decoder object for webp files a different chunk_size may work
import struct
import zlib

from django.core.files import File


class ImageFile(File):
    

    @property
    def width(self):
        return self._get_image_dimensions()[0]

    @property
    def height(self):
        return self._get_image_dimensions()[1]

    def _get_image_dimensions(self):
        if not hasattr(self, "_dimensions_cache"):
            close = self.closed
            self.open()
            self._dimensions_cache = get_image_dimensions(self, close=close)
        return self._dimensions_cache


def get_image_dimensions(file_or_path, close=False):
    
    from PIL import ImageFile as PillowImageFile

    p = PillowImageFile.Parser()
    if hasattr(file_or_path, "read"):
        file = file_or_path
        file_pos = file.tell()
        file.seek(0)
    else:
        try:
            file = open(file_or_path, "rb")
        except OSError:
            return (None, None)
        close = True
    try:
        
        
        
        chunk_size = 1024
        while 1:
            data = file.read(chunk_size)
            if not data:
                break
            try:
                p.feed(data)
            except zlib.error as e:
                
                
                if e.args[0].startswith("Error -5"):
                    pass
                else:
                    raise
            except struct.error:
                
                
                
                pass
            except RuntimeError:
                
                
                pass
            if p.image:
                return p.image.size
            chunk_size *= 2
        return (None, None)
    finally:
        if close:
            file.close()
        else:
            file.seek(file_pos)