예제 #1
0
    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))
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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()