Search code examples
ckeditorckeditor4.xdjango-ckeditor

ckeditor automatically visually resize dropped image


Is there a way to automatically visually resize dropped image in the ckeditor4 (I am using 4.7)? Often, the dragged image is too big in dimension. True, it is resizable, but the user need to go all the way to right bottom corner to resize it. What I would like to have is: once the image is dropped, it automatically resize to max_width: 600px, and height changes accordingly. Is this possible? BTW, I am using django-ckeditor. Thanks.


Solution

  • It turns out that ckeditor4 (likely after version 4.7?) has default function to take server-returned image width and height in Json response (as in uploadimage plugin.js).

                    onUploaded: function( upload ) {
                        // Width and height could be returned by server (https://dev.ckeditor.com/ticket/13519).
                        var $img = this.parts.img.$,
                            width = upload.responseData.width || $img.naturalWidth,
                            height = upload.responseData.height || $img.naturalHeight;
    

    By default though, Json response only returns uploaded, filename, and url doc here.

    So, in django-ckeditor, I had to modify ImageUploadView in ckeditor_uploader views.py to return width and height. The way I accomplish this is a bit ugly. If anyone has a better idea, please do edit my answer. BTW, this approach worked for both dropped image and pasted image.

    modify views.py as follow:

    add from PIL import Image to the top.

    modify ImageUploadView as follow:

    class ImageUploadView(generic.View):
        http_method_names = ['post']
    
        def post(self, request, **kwargs):
            """
            Uploads a file and send back its URL to CKEditor.
            """
            uploaded_file = request.FILES['upload']
    
            backend = registry.get_backend()
    
            ck_func_num = request.GET.get('CKEditorFuncNum')
            if ck_func_num:
                ck_func_num = escape(ck_func_num)
    
            filewrapper = backend(storage, uploaded_file)
            allow_nonimages = getattr(settings, 'CKEDITOR_ALLOW_NONIMAGE_FILES', True)
            # Throws an error when an non-image file are uploaded.
            if not filewrapper.is_image and not allow_nonimages:
                return HttpResponse("""
                    <script type='text/javascript'>
                    window.parent.CKEDITOR.tools.callFunction({0}, '', 'Invalid file type.');
                    </script>""".format(ck_func_num))
    
            filepath = get_upload_filename(uploaded_file.name, request.user)
    
            saved_path = filewrapper.save_as(filepath)
    
            url = utils.get_media_url(saved_path)
    
    ######to get width and height of image
    
            image = Image.open(filewrapper.file_object)
            print(image)
    
            if image.width > 800:
                factor = 800/image.width
                new_width = int(image.width*factor)
                new_height = int(image.height*factor)
    
                width = new_width
                height = new_height
            else: 
                width = image.width
                height = image.height
    
    ##############
            if ck_func_num:
                # Respond with Javascript sending ckeditor upload url.
                return HttpResponse("""
                <script type='text/javascript'>
                    window.parent.CKEDITOR.tools.callFunction({0}, '{1}');
                </script>""".format(ck_func_num, url))
            else:
                _, filename = os.path.split(saved_path)
                retdata = {'url': url, 'uploaded': '1',
                           'fileName': filename,
    ########## return width and height
                           'width': width, 'height': height} 
                return JsonResponse(retdata)
    
    
    upload = csrf_exempt(ImageUploadView.as_view())