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 panelTitle: 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:
|
_______________________________________________ Image-SIG maillist - Image-SIG@python.org http://mail.python.org/mailman/listinfo/image-sig