def test_get_min_size(self): from cropduster.utils import get_min_size from cropduster.resizing import Size sizes = [ Size('a', w=200, h=200), Size('b', w=100, h=300), Size('c', w=20, h=20) ] self.assertEqual(get_min_size(sizes), (200, 300)) sizes = [ Size('a', min_w=200, min_h=200, max_h=500), Size('b', min_w=100, min_h=300), Size('c', w=20, h=20) ] self.assertEqual(get_min_size(sizes), (200, 300))
def clean_upload_data(data): image = data['image'] image.seek(0) try: pil_image = PIL.Image.open(image) except IOError as e: if e.errno: error_msg = force_text(e) else: error_msg = u"Invalid or unsupported image file" raise forms.ValidationError({"image": [error_msg]}) else: extension = get_image_extension(pil_image) upload_to = data['upload_to'] or None folder_path = get_upload_foldername(image.name, upload_to=upload_to) (w, h) = (orig_w, orig_h) = pil_image.size sizes = data.get('sizes') if sizes: (min_w, min_h) = get_min_size(sizes) if (orig_w < min_w or orig_h < min_h): raise forms.ValidationError({ "image": [(u"Image must be at least %(min_w)sx%(min_h)s " u"(%(min_w)s pixels wide and %(min_h)s pixels high). " u"The image you uploaded was %(orig_w)sx%(orig_h)s pixels.") % { "min_w": min_w, "min_h": min_h, "orig_w": orig_w, "orig_h": orig_h }] }) if w <= 0: raise forms.ValidationError( {"image": [u"Invalid image: width is %d" % w]}) elif h <= 0: raise forms.ValidationError( {"image": [u"Invalid image: height is %d" % h]}) # File is good, get rid of the tmp file orig_file_path = os.path.join(folder_path, 'original' + extension) image.seek(0) md5_hash = hashlib.md5() default_storage.save(orig_file_path, image) with default_storage.open(orig_file_path) as f: md5_hash.update(f.read()) f.seek(0) data['image'] = f data['md5'] = md5_hash.hexdigest() return data
def clean_upload_data(data): image = data['image'] image.seek(0) try: pil_image = PIL.Image.open(image) except IOError as e: if e.errno: error_msg = force_text(e) else: error_msg = u"Invalid or unsupported image file" raise forms.ValidationError({"image": [error_msg]}) else: extension = get_image_extension(pil_image) upload_to = data['upload_to'] or None folder_path = get_upload_foldername(image.name, upload_to=upload_to) (w, h) = (orig_w, orig_h) = pil_image.size sizes = data.get('sizes') if sizes: (min_w, min_h) = get_min_size(sizes) if (orig_w < min_w or orig_h < min_h): raise forms.ValidationError({"image": [( u"Image must be at least %(min_w)sx%(min_h)s " u"(%(min_w)s pixels wide and %(min_h)s pixels high). " u"The image you uploaded was %(orig_w)sx%(orig_h)s pixels.") % { "min_w": min_w, "min_h": min_h, "orig_w": orig_w, "orig_h": orig_h }]}) if w <= 0: raise forms.ValidationError({"image": [u"Invalid image: width is %d" % w]}) elif h <= 0: raise forms.ValidationError({"image": [u"Invalid image: height is %d" % h]}) # File is good, get rid of the tmp file orig_file_path = os.path.join(folder_path, 'original' + extension) image.seek(0) image_contents = image.read() with open(os.path.join(settings.MEDIA_ROOT, orig_file_path), 'wb+') as f: f.write(image_contents) md5_hash = hashlib.md5() md5_hash.update(image_contents) data['md5'] = md5_hash.hexdigest() data['image'] = open(os.path.join(settings.MEDIA_ROOT, orig_file_path), mode='rb') return data
def import_from_cropduster_field_file(item, field, image_field_file, commit=True): cropduster_image = image_field_file.related_object original_image_path = image_field_file.path sizes = getattr(item, field).sizes required_w, required_h = get_min_size(sizes) if cropduster_image.width < required_w or cropduster_image.height < required_h: raise ImageImportError("article image is not large enough") setattr(item, field, image_field_file.name) new_image = Image.objects.create( content_type=ContentType.objects.get_for_model(item), object_id=item.pk, field_identifier=item._meta.get_field(field).field_identifier, width=cropduster_image.width, height=cropduster_image.height, image=image_field_file.name, attribution=cropduster_image.attribution, attribution_link=cropduster_image.attribution_link, caption=cropduster_image.caption) getattr(item, field).related_object = new_image for size in sizes: existing_thumbs = cropduster_image.thumbs.filter(reference_thumb__isnull=True) existing_crops = [Crop(t.get_crop_box(), original_image_path) for t in existing_thumbs] existing_crops.sort(key=lambda c: crop_overlap(size.fit_to_crop(c), c)) best_crop = existing_crops[-1] new_crop = size.fit_to_crop(best_crop) new_thumb = Thumb( name=size.name, width=size.width, height=size.height, crop_x=new_crop.box.x1, crop_y=new_crop.box.y1, crop_w=new_crop.box.w, crop_h=new_crop.box.h, image=new_image) new_thumbs = new_image.save_size(size, new_thumb) for thumb_name, thumb in new_thumbs.iteritems(): thumb.image = new_image thumb.save() if commit: item.save()