예제 #1
0
    def create_image(self, output_filename, width, height):
        from cropduster.utils import process_image, get_image_extension

        temp_file = tempfile.NamedTemporaryFile(suffix=get_image_extension(self.image), delete=False)
        temp_filename = temp_file.name
        with open(self.image.filename, mode='rb') as f:
            temp_file.write(f.read())
        temp_file.seek(0)
        image = PIL.Image.open(temp_filename)

        crop_args = self.box.as_tuple()

        def crop_and_resize_callback(im):
            from cropduster.utils import smart_resize
            im = im.crop(crop_args)
            return smart_resize(im, final_w=width, final_h=height)

        new_image = process_image(image, output_filename, crop_and_resize_callback)
        new_image.crop = self
        temp_file.close()
        os.unlink(temp_filename)
        return new_image
예제 #2
0
    def create_image(self, output_filename, width=None, height=None, max_w=None, max_h=None):
        from cropduster.exceptions import CropDusterResizeException
        from cropduster.utils import process_image, get_image_extension

        new_w, new_h = self.box.size
        if new_w < width or new_h < height:
            raise CropDusterResizeException(
                u"Crop box (%dx%d) is too small for resize to (%dx%d)" % (new_w, new_h, width, height))

        # Scale our initial width and height based on the max_w and max_h
        max_scales = []
        if max_w and max_w < width:
            max_scales.append(max_w / width)
        if max_h and max_h < height:
            max_scales.append(max_h / height)
        if max_scales:
            max_scale = min(max_scales)
            width = int(round(width * max_scale))
            height = int(round(height * max_scale))

        temp_file = tempfile.NamedTemporaryFile(suffix=get_image_extension(self.image), delete=False)
        temp_filename = temp_file.name
        with open(self.image.filename, mode='rb') as f:
            temp_file.write(f.read())
        temp_file.seek(0)
        image = PIL.Image.open(temp_filename)

        crop_args = self.box.as_tuple()

        def crop_and_resize_callback(im):
            from cropduster.utils import smart_resize
            im = im.crop(crop_args)
            return smart_resize(im, final_w=width, final_h=height)

        new_image = process_image(image, output_filename, crop_and_resize_callback)
        new_image.crop = self
        temp_file.close()
        os.unlink(temp_filename)
        return new_image
예제 #3
0
    def create_image(self, output_filename, width, height):
        from cropduster.utils import process_image, get_image_extension

        temp_file = tempfile.NamedTemporaryFile(suffix=get_image_extension(self.image), delete=False)
        temp_filename = temp_file.name
        with default_storage.open(self.image.filename, mode='rb') as f:
            temp_file.write(f.read())
        temp_file.seek(0)
        image = PIL.Image.open(temp_filename)
        image.filename = self.image.filename

        crop_args = self.box.as_tuple()

        def crop_and_resize_callback(im):
            from cropduster.utils import smart_resize
            im = im.crop(crop_args)
            return smart_resize(im, final_w=width, final_h=height)

        new_image = process_image(image, output_filename, crop_and_resize_callback)
        new_image.crop = self
        temp_file.close()
        os.unlink(temp_filename)
        return new_image
예제 #4
0
def upload(request):
    if request.method == 'GET':
        return index(request)

    # The data we'll be returning as JSON
    data = {
        'warning': [],
    }

    form = UploadForm(request.POST, request.FILES)

    if not form.is_valid():
        errors = form['image'].errors or form.errors
        return json_error(request,
                          'upload',
                          action="uploading file",
                          errors=[force_text(errors)])

    form_data = form.cleaned_data
    is_standalone = bool(form_data.get('standalone'))

    orig_file_path = form_data['image'].name
    if six.PY2 and isinstance(orig_file_path, six.text_type):
        orig_file_path = orig_file_path.encode('utf-8')
    orig_image = get_relative_media_url(orig_file_path)

    with default_storage.open(orig_image, mode='rb') as f:
        img = PIL.Image.open(BytesIO(f.read()))
        img.filename = f.name

    (w, h) = (orig_w, orig_h) = img.size

    if is_animated_gif(img) and not has_animated_gif_support():
        data['warning'].append(
            u"This server does not have animated gif support; your uploaded image "
            u"has been made static.")

    tmp_image = Image(image=orig_image)
    preview_w = form_data.get('preview_width') or PREVIEW_WIDTH
    preview_h = form_data.get('preview_height') or PREVIEW_HEIGHT

    # First pass resize if it's too large
    resize_ratio = min(preview_w / w, preview_h / h)

    def fit_preview(im):
        (w, h) = im.size
        if resize_ratio < 1:
            w = int(round(w * resize_ratio))
            h = int(round(h * resize_ratio))
            preview_img = im.resize((w, h), PIL.Image.ANTIALIAS)
        else:
            preview_img = im
        return preview_img

    if not is_standalone:
        preview_file_path = tmp_image.get_image_path('_preview')
        process_image(img, preview_file_path, fit_preview)

    data.update({
        'crop': {
            'orig_image': orig_image,
            'orig_w': orig_w,
            'orig_h': orig_h,
            'image_id': None,
        },
        'url': tmp_image.get_image_url('_preview'),
        'orig_image': orig_image,
        'orig_w': orig_w,
        'orig_h': orig_h,
        'width': w,
        'height': h,
    })
    if not is_standalone:
        return HttpResponse(json.dumps(data), content_type='application/json')

    size = Size('crop', w=img.size[0], h=img.size[1])

    md5 = form_data.get('md5')
    try:
        standalone_image = StandaloneImage.objects.get(md5=md5)
    except StandaloneImage.DoesNotExist:
        standalone_image = StandaloneImage(md5=md5, image=orig_image)
        standalone_image.save()
    cropduster_image, created = Image.objects.get_or_create(
        content_type=ContentType.objects.get_for_model(StandaloneImage),
        object_id=standalone_image.pk)

    if not cropduster_image.image:
        cropduster_image.image = orig_image
        cropduster_image.save()
    elif cropduster_image.image.name != orig_image:
        data['crop']['orig_image'] = data[
            'orig_image'] = cropduster_image.image.name
        data['url'] = cropduster_image.get_image_url('_preview')

    with cropduster_image.image as f:
        f.open()
        img = PIL.Image.open(BytesIO(f.read()))
        img.filename = f.name
    preview_file_path = cropduster_image.get_image_path('_preview')
    if not default_storage.exists(preview_file_path):
        process_image(img, preview_file_path, fit_preview)

    thumb = cropduster_image.save_size(size, standalone=True, commit=False)

    sizes = form_data.get('sizes') or []
    if len(sizes) == 1:
        size = sizes[0]
    else:
        size = Size('crop')

    data.update({
        'thumbs': [{
            'crop_x': thumb.crop_x,
            'crop_y': thumb.crop_y,
            'crop_w': thumb.crop_w,
            'crop_h': thumb.crop_h,
            'width': thumb.width,
            'height': thumb.height,
            'id': None,
            'changed': True,
            'size': json.dumps(size),
            'name': thumb.name,
        }]
    })
    data['crop'].update({
        'image_id': cropduster_image.pk,
        'sizes': json.dumps([size]),
    })
    return HttpResponse(json.dumps(data), content_type='application/json')
예제 #5
0
def upload(request):
    if request.method == 'GET':
        return index(request)

    # The data we'll be returning as JSON
    data = {
        'warning': [],
    }

    form = UploadForm(request.POST, request.FILES)

    if not form.is_valid():
        errors = form['image'].errors or form.errors
        return json_error(request, 'upload', action="uploading file",
                errors=[force_text(errors)])

    form_data = form.cleaned_data
    is_standalone = bool(form_data.get('standalone'))

    orig_file_path = form_data['image'].name
    if six.PY2 and isinstance(orig_file_path, unicode):
        orig_file_path = orig_file_path.encode('utf-8')
    orig_image = get_relative_media_url(orig_file_path)
    img = PIL.Image.open(orig_file_path)
    (w, h) = (orig_w, orig_h) = img.size

    if is_animated_gif(img) and not has_animated_gif_support():
        data['warning'].append(
            u"This server does not have animated gif support; your uploaded image "
            u"has been made static.")

    tmp_image = Image(image=orig_image)
    preview_w = form_data.get('preview_width') or PREVIEW_WIDTH
    preview_h = form_data.get('preview_height') or PREVIEW_HEIGHT

    # First pass resize if it's too large
    resize_ratio = min(preview_w / w, preview_h / h)

    def fit_preview(im):
        (w, h) = im.size
        if resize_ratio < 1:
            w = int(round(w * resize_ratio))
            h = int(round(h * resize_ratio))
            preview_img = im.resize((w, h), PIL.Image.ANTIALIAS)
        else:
            preview_img = im
        return preview_img

    if not is_standalone:
        preview_file_path = tmp_image.get_image_path('_preview')
        process_image(img, preview_file_path, fit_preview)

    data.update({
        'crop': {
            'orig_image': orig_image,
            'orig_w': orig_w,
            'orig_h': orig_h,
            'image_id': None,
        },
        'url': tmp_image.get_image_url('_preview'),
        'orig_image': orig_image,
        'orig_w': orig_w,
        'orig_h': orig_h,
        'width': w,
        'height': h,
    })
    if not is_standalone:
        return HttpResponse(json.dumps(data), content_type='application/json')

    size = Size('crop', w=img.size[0], h=img.size[1])

    md5 = form_data.get('md5')
    try:
        standalone_image = StandaloneImage.objects.get(md5=md5)
    except StandaloneImage.DoesNotExist:
        standalone_image = StandaloneImage(md5=md5, image=orig_image)
        standalone_image.save()
    cropduster_image, created = Image.objects.get_or_create(
        content_type=ContentType.objects.get_for_model(StandaloneImage),
        object_id=standalone_image.pk)

    if not cropduster_image.image:
        cropduster_image.image = orig_image
        cropduster_image.save()
    elif cropduster_image.image.name != orig_image:
        data['crop']['orig_image'] = data['orig_image'] = cropduster_image.image.name
        data['url'] = cropduster_image.get_image_url('_preview')

    img = PIL.Image.open(cropduster_image.image.path)
    preview_file_path = cropduster_image.get_image_path('_preview')
    if not os.path.exists(preview_file_path):
        process_image(img, preview_file_path, fit_preview)

    thumb = cropduster_image.save_size(size, standalone=True)

    sizes = form_data.get('sizes') or []
    if len(sizes) == 1:
        size = sizes[0]
    else:
        size = Size('crop')

    data.update({
        'thumbs': [{
            'crop_x': thumb.crop_x,
            'crop_y': thumb.crop_y,
            'crop_w': thumb.crop_w,
            'crop_h': thumb.crop_h,
            'width':  thumb.width,
            'height': thumb.height,
            'id': None,
            'changed': True,
            'size': json.dumps(size),
            'name': thumb.name,
        }]
    })
    data['crop'].update({
        'image_id': cropduster_image.pk,
        'sizes': json.dumps([size]),
    })
    return HttpResponse(json.dumps(data), content_type='application/json')