If its a memory issue like people have suggested, then it's still possible to do.  You could break the image into chunks, resize those, then re-assemble them.  The .tile attribute will help you.  I've personally worked with files up to about 1.5GB with PIL successfully - even on a 600mHz computer with only 2GB of RAM (back in about 2000), but I'm not sure where the limit actually is, if any.

I'm looking for a good code sample to show you how to use the .tile attribute for this, but can't find any yet… the attached is pretty cryptic and horrible coding (from my "early" years :) with little useful documentation.  Fredrik really helped me understand it back then, so if you search the newsgroup archives for ".tile" you should probably find something useful.

You'd have to do something like:

1)  open the image
2)  modify the .tile attribute so that you're only working with a portion of the image (that you can handle in memory)
3)  resize the image
4)  save that portion of the image
5)  repeat the above for all sections of the image
6)  load them all and paste the resized ones back into one smaller image

I'd suggest that you have a bit of overlap in the files though, or you'll have artifacts where you paste them together.  This is due to the resampling errors right at the edge of an image.

# Build Image module by Kevin Cazabon
# Version 1.0
# Copyright 1999.  kc...@cymbolic.com

print 'Build Image version 1.0 by Kevin Cazabon.  Copyright 1999'



def build_image(imagename, crop_coords, outsize, outmode):

    """ Method for 'building' an image in memory from a cropped portion of a larger file.
        The advantage of this method is that the original image does NOT have to be loaded
        entirely into memory at once.  Only the cropped portion, plus ONE line is held in mem.
        For now, outsize MUST be the same as the total area defined by crop_coords.
        This will only work with UNCOMPRESSED image formats (BMP, TIF, etc.) 
        
        by Kevin Cazabon kc...@cymbolic.com June/99 """
        
    import Image
    
    im = Image.open(imagename)
    im_size = im.size
    im_mode = im.mode
    im_tile = im.tile
    
    del(im)
    
    if im_tile[0][0] == 'raw':
    
        if outmode == 'RGB':
            channels = 3
        elif outmode == 'CMYK':
            channels = 4
        else:
            channels = 3        
        
        # check if cropping is outside of real image area
        
        pad_l = 0
        pad_t = 0
        pad_r = 0
        pad_b = 0
        
        if crop_coords[0] < 0:
            pad_l= pad_l - crop_coords[0]
            crop_coords[0] = 0
        if crop_coords[1] < 0:
            pad_t = pad_t - crop_coords[1]
            crop_coords[1] = 0
        if crop_coords[2] > im_size[0]:
            pad_r = crop_coords[2] - im_size[0]
            crop_coords[2] = im_size[0]
        if crop_coords[3] > im_size[0]:
            pad_b = crop_coords[3] - im_size[1]
            crop_coords[3] = im_size[1]
            
        # create background image at outsize
        
        panel = Image.new(outmode, outsize)
    
        # loop through reading image line-by-line and pasting into background

        paste = 'yes'
        line_num = 0
        
        while paste == 'yes':
            
            this_line = Image.open(imagename)
            file_offset = this_line.tile[0][2] + ((crop_coords[1] + line_num)*channels*this_line.size[0]) + (crop_coords[0] * channels)
            args = this_line.tile[0][3]
            
            this_line.size = (crop_coords[2] - crop_coords[0], 1)
            this_line.tile = [('raw', (0,0,this_line.size[0],1), file_offset, args)]
            
            try:
                this_line.load()
            except IOError:
                paste = 'no'
                
            #this_line = this_line.crop((crop_coords[0], 0, crop_coords[2], 1))
            
            if this_line.mode != outmode:
                this_line = this_line.convert(outmode)
                
            panel.paste(this_line, (pad_l, pad_t + line_num))
                                    
            del(this_line)
        
            line_num = line_num + 1
                
            if line_num > panel.size[1]:
                paste = 'no'

    else:
        print 'Image is compressed, cannot build cropped image in memory.'
        return None                

    return panel
Title: What is the best way to anti-alias a very large resolution image in PIL


Good luck!

Kevin.





On Sep 8, 2011, at 7:07 AM, Craig Coleman (C) wrote:

Hi,

I have a really thorny problem.

I need to downsample a raster map that is 23622x23622 pixels to 7874x7874 pixels using the ANTIALIAS filter.

I have the following Python code:

>>> import Image
>>> img = Image.open(r"C:\temp\24bit_nd.tif")
>>> nimg = img.resize((7874,7874),Image.ANTIALIAS)

As soon as the resize method is called, python crashes instantly.  I presume this is a memory allocation issue.

Is there another way of performing anti-aliasing on such a large image (its 2.7GB uncompressed although I'm using LZW for storage).

I have tried converting the file to 8bit with a palette and this successfully downsamples but the ANTIALIAS is not performed.  What am I doing wrong?

Craig Coleman
Technical Lead
Information Systems, Ordnance Survey

L0F2, Adanac Drive, SOUTHAMPTON, United Kingdom, SO16 0AS
Phone: +44 (0) 2380 054641
www.ordnancesurvey.co.uk | craig.cole...@ordnancesurvey.co.uk
Please consider your environmental responsibility before printing this email.

This email is only intended for the person to whom it is addressed and may contain confidential information. If you have received this email in error, please notify the sender and delete this email which must not be copied, distributed or disclosed to any other person.

Unless stated otherwise, the contents of this email are personal to the writer and do not represent the official view of Ordnance Survey. Nor can any contract be formed on Ordnance Survey's behalf via email. We reserve the right to monitor emails and attachments without prior notice.

Thank you for your cooperation.

Ordnance Survey
Adanac Drive
Southampton SO16 0AS
Tel: 08456 050505
http://www.ordnancesurvey.co.uk

_______________________________________________
Image-SIG maillist  -  Image-SIG@python.org
http://mail.python.org/mailman/listinfo/image-sig

_______________________________________________
Image-SIG maillist  -  Image-SIG@python.org
http://mail.python.org/mailman/listinfo/image-sig

Reply via email to