Jul 22, 2014

Unexpected file uploading solutions from customers of Uploadcare

Successful startups usually begin with an idea that helps solving a specific problem which has not yet been solved efficiently. It’s important to be focused, otherwise you will end up doing everything and nothing really well. It was true for Uploadcare too. We were focused on a very specific task: image uploads to the CDN and simple crop/resize/transform operations on the uploaded images.

However, no one will tell you what is really expected from your startup better than your customer. Today image uploads is just a segment of our business. Customers found other efficient ways to use Uploadcare, we could not even think about at the beginning.

I would like to highlight two of such success stories: Unidesk and PandaDoc.

Uploading large files for Salesforce in combination with Skuid

Good example is the case about how Unidesk, one of our customers, solved large file uploading problem.

While implementing a support management system on top of Skuid (UI toolkit for Salesforce), one of the requirements was to make users able to upload attachments to the support tickets. Salesforce does have file uploading capabilities, but as it isn’t the main purpose of the CRM, there are limitations on file size and issues with uploading reliability.

That’s where Uploadcare comes into play, with its asynchronous file uploading capability, support of huge files and easy integration. The solution was implemented by a founder and described in details in Skuid community blog.

Want to go paperless? Need to upload!

In 1869 the New Hampshire Supreme Court accepted telegraphic messages as a legitimate way of signing agreements:

"It makes no difference whether that operator writes the offer or the acceptance with a steel pen an inch long attached to an ordinary penholder, or whether his pen be a copper wire a thousand miles long."

Although signing documents electronically was legal, it was impractical at that time due to lack of technology. Even today there are certain barriers to use electronic signatures. The first barrier is file uploading.

PandaDoc, a San-Francisco based company that specializes on electronic signatures choose Uploadcare as the way for their customers to upload documents to sign. The use case is uncommon indeed! Possibility to integrate with Google Drive and other cloud-based storages was one of the major advantages for using our widget. They tweaked the widget according to the needs, and implemented support of custom OAuth applications.

Check out this video to see how PandaDoc applied Uploadcare to their use case.

Jul 15, 2014

Uploadcare on StackOverflow

As Uploadcare becomes popular, users starting to ask repeated questions about integration and usage. Yet some of the topics are not yet covered in the documentation. Also, reading documentation takes time, and our customers are primarily fast-growing start ups where every minute counts.

So, we decided to be more active on StackOverflow, and create an open knowledge base for our service:


You can use tag [uploadcare] to ask questions and search for answers. We encourage anyone who had experience of customizing the widget or any part of the system:

Please, share your solution with others!

It’s time to start building community. Let’s make our first steps on StackOverflow!

Uploadcare team

Apr 3, 2014

Uploadcare on Social Networks and Cloud Servers Security

Uploadcare allows users to easily upload files from a growing number of social networks and cloud services. Which raises the obvious question — is it safe? And can others read or even modify user files that are not uploaded to Uploadcare but stored in cloud services? To answer all of these questions, we’d like to explain how Uploadcare works with third-party services.

Uploadcare Neither Requests nor Stores User Passwords

All interaction with services is done over the OAuth or OAuth2 protocols. The way they operate is roughly the same:

  1. The user presses the “Connect to Service” button in the Uploadcare widget. A new tab or window of the selected social network or cloud service is opened.
  2. The service asks the user to enter his or her username and password on it’s website.
  3. The service requests permission to provide Uploadcare access to it’s data.
  4. The service provides Uploadcare with a key, so called “access token”.
  5. Uploadcare uses the access token to access user data.

Step 2 may be skipped if the user is already logged into the service. Step 3 may be skipped if the user has previously allowed access to their data. Steps 2 and 3 can be presented on a single page. This all depends on the service.

The service does not provide Uploadcare with user credentials. Users can revoke access from Uploadcare at any time (this is done on the service side, usually in account settings).

The Site Owner Cannot Interfere With Service Interaction

The authorization and file selection is implemented in the widget, but actually occurs within iframe. Iframe is an HTML element that allows one to open documents from a different domain from within a current document. Thus an external site on which the widget is installed cannot receive any events or data from a document containing a list of user files. The only event that occurs in the widget itself is the user’s selection of a particular file.

Even if the owner of the site on which the Uploadcare widget is installed is ill intentioned, he or she cannot actually get a list of user files or any other form of access to them. The only files he or she has access to is those that have been explicitly chosen by the user. The same rule applies if the site owner uses his own application for the service.

Uploadcare Does Not Have Access to User Data

Sounds weird, but it’s true. We understand that there always remains a remote possibility of server hacking. If someone gained access to an application server that stores access tokens of a large number of users (reference to one of our competitors goes here:), he would then have access to all the files stored in the cloud services of those users. Which is why we do not store access tokens in any way, shape or form. Instead the access token is passed along to the server with each request. The only one who can access his files is the user himself.

The Access Token Cannot Be Intercepted and Decoded

Our service works via the SSL protocol. This means that all traffic between user’s browser and our servers is encrypted, so the attacker will have a very difficult time obtaining the access token from queries. But still, the access token is the key that provides full access to user files, and thus should not fall into the wrong hands even when data is successfully intercepted. Due to this we further encrypt the access token passed in the request so it cannot be used anywhere but on our own server.

Sep 19, 2013

Please Speak out Loud

Hello friends!

We have an offer for you: You have a great chance to get 3 months of unlimited usage of Uploadcare (any plan, no limits). You’ll get a great media storage and CDN, so your blog will become up to 5x faster.

What you need to do for that? Make a review of Uploadcare and publish it to your blog. So simple!

By the way, we have free Wordpress plugin, it will take you 3 minutes to install Uploadcare to your blog. Otherwise sign up here.

To apply, just send us a link to your blog post at hello@uploadcare.com

The Uploadcare Team


Jul 19, 2013

How to customize widget for file uploads

New-era services like Uploadcare allow users to integrate all cloud resources with applications and websites. Although in-built widgets make a great service making it easy to choose and add deliver files on the web, some nice customization will never be redundant.

Here an example of widget customization will be shown. Start with Uploadcare Quick Start page to install the basic version of the uploader.

However, in advanced cases you may want to use your own design or logic. In this case, you want to use Uploadcare JS API to customize the behaviour of our widget.

To use Uploadcare JS API, you have to add this to the <head> of your web page:

<!-- The best place for this one is your <HEAD> tag -->
<script>UPLOADCARE_PUBLIC_KEY = "demopublickey";</script>
<script src="https://ucarecdn.com/widget/0.10/uploadcare/uploadcare-0.10.min.js"></script>

Replace “demopublickey” with your own public key if you’re signed up with Uploadcare. If you’re not, you can use this demo key for now, it works just fine, but files uploaded to this account are being periodically cleaned up.

First thing that happens to a file is it being uploaded. If you’re using our widget, visitors of your website can upload a file by drag-n-dropping it on the widget, or by opening a dialog and choosing a file from their computer or social network accounts, or by copy-pasting its url.

From the JS API perspective, you can upload file from any URL or from an event objet (like a dragndrop event):

var file = uploadcare.fileFrom('url', 'http://example.com/image.png');
var droppedFile = uploadcare.fileFrom('event', e);

To construct a file object from a file, already uploaded to your account, you can use the same method:

var droppedFile = uploadcare.fileFrom('uploaded', '61783708-7090-4d6a-b82b-81f98e40a327');

You can also show a dialog to let the user select a file she wants to upload:

var dialog = widget.openDialog();
dialog.done(function(file) {
    // file was selected

 Uploadcare JS API is based on Deferreds. Deferred is an object which can be done, failed or in progress. As you can see, Dialog is a deferred: it’s “done” when user have chosen a file, “failed” if she decided not to, and “in progress” until any of these happens.

Uploadcare File is a deferred, too: it can be already uploaded, the upload may had been failed, or it can be uploading at this moment.

The point of Deferred is management of callbacks. You can add new callbacks to be called after the file, for example, is uploaded:

file.done(function(fileInfo) {
    // Upload successfully completed and file is ready.
}).fail(function(error, fileInfo) {
    // Upload failed or something else went wrong.
}).progress(function(uploadInfo) {
    // State of upload is updated.
    // This callback is invoked at least once with current state,
    // immediately after assignment.

You can use a file promise to output the progress of an upload, like this:

file.progress(function(info) {
        uploading: 'Uploading...',
        uploaded: 'Loading info...',
        ready: 'Done.'
    console.log(info.progress) // percentage of a file uploaded

This function will be called many times while the file is uploading, so you can output a progress bar. We have a progress circle in our JS bundle, which can be used just like this:

var circle = uploadcare.Circle('#progress');
circle.listen(file, 'progress');

You can read more about our JS API in the documentation.

May 29, 2013

Image hosting in 30 minutes


How to create an image hosting service in the easiest way?

It used to be fairly simply, but progress marches on, and today many factors need to be taken into account. Uploadcare makes working with files easier. Everything from uploading, storage, processing, to distribution to the end user. Let us use it as our primary block.

The examples are given in Python, because the
pyuploadcare library receives priority updates. Of course Uploadcare has libraries for an assortment of different languages, all of them opensource. If the module you’re working with is missing some functionality, you can either wait for it to appear, or simply add it yourself.

Let’s begin by creating a new project in Django:

$ pip install django pyuploadcare==0.19
$ django-admin.py startproject upload_test
$ cd upload_test/ && chmod u+x ./manage.py
$ ./manage.py startapp imageshare
$ ./manage.py syncdb —noinput

In settings.py, in addition to the usual settings for connecting to the database and INSTALLED_APPS, you need to specify the public and private keys:

    'pub_key': 'demopublickey',
    'secret': 'demoprivatekey',

For purposes of demonstration, We’ll be using a demo account. The only limitation for this account is that the files are eventually automatically deleted.

As an example we add the upload form on the home page. And the image ID will be saved to the database after the file is sent. To do so we only need a model like:

import string
import random
from pyuploadcare.dj import ImageField
from django.db import models

class Image(models.Model):
    slug = models.SlugField(max_length=10, primary_key=True, blank=True)
    image = ImageField(manual_crop="")

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = ''.join(random.sample(string.ascii_lowercase, 6))
        super(Image, self).save(*args, **kwargs)

As you can probably notice, the ImageField we’re using isn’t from Django, but from the pyuploadcare library. We’ve only specified a single setting: it will allow the user to select the area of ​​the image that he wants to download. The save () method generates a slug for a short link.

Now the nifty part: the home page form for saving the image and the form that allows us to view the upload:

from django.views.generic import DetailView
from django.views.generic.edit import CreateView
from .models import Image

class UploadView(CreateView):
    model = Image

class ImageView(DetailView):
    model = Image

Class, in 2 lines. Django by itself is also a great building block for your projects. In order to display the form you will need a small template. Nothing out of the ordinary, but you have to specify the public key for the widget, and don’t forget to put a document tag {{form.media}}. Often people forget about this attribute.

{% extends "base.html" %}

{% block head %}
    UPLOADCARE_PUBLIC_KEY = 'demopublickey';
    {{ form.media }}
{% endblock %}

{% block body %}
    <div class="center">
        <form action="." method="post">
            <p>Please, select an image:</p>
            <p>{{ form.image }}</p>
            <p><input type="submit" value="send"></p>
            {{ form.errors }}
{% endblock %}

Load it.


A widget for selecting files will appear on the page. But saving doesn’t seem to work, Django just spouts “No URL to redirect to”. Which is understandable, as you need to point where you’ll be getting the full url for the image. Let’s add one more method to the model.

    def get_absolute_url(self):
        return 'detail', (), {'pk': self.pk}

Now all we need to do is create a template for output, and mission accomplished!

{% block body %}
    <img src="{{ image.image }}">
{% endblock %}

The fellows from our Instagram all say hello.

The attentive reader will notice that everything covered to this point took 15 minutes at most. Damn, how are we going to kill the other 15?

Upload page improvement

In its current version the user has to perform 2 extra clicks: to open the widget, and to submit the form. We can do without both. To do so you need to use the javascript api widget:

(function() {

    var widget = uploadcare.Widget('#id_image');
    widget.onChange(function(file) {
        if (file) {
            var form = document.getElementById('upload-form');
            form.style.display = 'none';

Here we initialize the widget by using the start (), so we’re not waiting for the page to load, and then we open the dialogue, without waiting for the user to click. And if a file is uploaded, we submit a form.

What else? You can also make the image view page a bit more informative, by showing a preview picture instead of the full picture, and outputting more information.

{% block body %}
    <h2>Uploaded Image</h2>

    <a href="{{ image.image.cdn_url }}">
        <img align="left" src="{{ image.image.cdn_url }}-/stretch/off/-/resize/260x/"></a>

    <div class="float-info">
            <b>Filename</b>: {{ image.image.info.filename }}<br>
            <b>Uploaded</b>: {{ image.image.info.datetime_uploaded|slice:":10" }}<br>
            <b>Original size</b>: {{ image.image.info.size|filesizeformat }}<br>

        <p><a href="{{ image.image.cdn_url }}">Full link</a></p>
    <br clear="left">
    <p><a href="{% url 'index' %}">Upload another image</a></p>
{% endblock %}

The thumbnail size is obtained by specifying its settings directly in the url of the image. Information is obtained through the info method. Unfortunately, datetime_uploaded is given as a string, so we had to cheat and cut the first 10 characters. Parsing it would have been the proper thing to do. Here’s hoping someone fixes it by the year 10000 :)


Handling of an deleted image
How to provide a 404 instead of a 500? This is best done when retrieving an object from the database: you request file information, and if there is indication that the file is deleted, you delete the stored link. Additionally, if a file was deleted a long time ago, the api may provide no info at all. You’ll need to handle this occurence as well.

class ImageView(DetailView):
    model = Image

    def get_object(self):
        object = super(ImageView, self).get_object()
            if object.image.is_removed:
                raise ValueError('File was deleted.')
        except (InvalidRequestError, ValueError):
            raise Http404

        return object

This seems like the place to stop.
All that remains to do is activate the last block - the free (up to a certain load) hosting service heroku - and see the results: iamshare.herokuapp.com. The source code is also available, in case anyone wants to see the whole thing together.

May 22, 2013

Plugin for Wordpress

Uploadcare provides media uploading, processing and CDN for your blog. You can upload even very large images and crop them.

Core features are:


  • Upload images of any resolution
  • Crop images
  • Upload documents and archives
  • Choose images from Facebook, Instagram or Flickr
  • Choose files from Dropbox or Google Drive
  • Deliver your media through CDN, it’s up to 5x times faster

Fastest way to install is following:

  1. In plugin manager, click “Add New”
  2. Search for “uploadcare”
  3. Click “install”
  4. Activate the plugin once it is installed
  5. Go to “Settings” -> “Uploadcare settings” and enter the public and secret keys for your account.

To receive your keys, create your FREE account at Uploadcare

To learn more and download go to Wordpress plugins  


May 22, 2013

No headache with file storage anymore

In many of its features, Uploadcare provides a solid and secure solution out of the box, but not at the expense of flexibility. One such feature is the ability to easily, but finely control which user-uploaded files you really need, and which ones can be discarded.

Autostore features

If you are using the “autostore” feature of the Uploadcare widget, the default behavior of an Uploadcare project is to accept every file that gets thrown at it, store it in the cloud on S3, and make a public CDN link for it. This is called “autostoring”, which is part of a broader concept of “storing” files.

Of course, at scale it may not be desireable to store each and every file, because that easily wastes space. Some of the uploaded files are there by mistake, e.g. when a user changes his file selection multiple times before submitting the form, or submits only part of a file set in a multiupload dialog.

To keep only those files that your application will really serve, “autostore” can be disabled in favor of a simple mechanism of control.

Fine Control over Uploads

The “autostore” feature can be enabled or disabled on the fly on the settings page of a given project. When it’s disabled, you (the application owner) have to explicitly and manually state which of the uploaded files you want to keep. Thankfully, it’s easier than it may sound.

It works like this.

Without “autostore”, every file uploaded to any of your Uploadcare projects is marked as temporary upon upload. All such temporary files are automatically deleted after 24 hours from the time of their upload. They’re also not available publicly, i.e. there is no CDN link for them. But, all temporary files, their attributes, and data are still available via the Uploadcare REST API.

In a way, temporary state is a file’s personal limbo. The hosting application needs to make a decision to keep it in 24 hours’ time, or simply ignore it, thus allowing it to be automatically discarded.

To “store” (keep) a file, you need to make an API request from your server-side code. The typicall place for such a request is the form submission handler.

PUT /files/:uuid/storage/

Of course, you need to substitute :uuid with a real UUID of whatever file you wish to keep. As soon as you do this, it’s going to be stored on S3 forever or until deletion. At the same time, a public CDN link is going to be created. In the case of image files, this also allows you and your users to apply CDN operations.

This way, your application never has to deal with files uploaded by accident, as they’re not even submitted with a form. In the simplest scenario you just send a store request for each submitted file (Uploadcare libraries for your language or framework of choice usually do it for you). Plus, you have optional fine control over what files to keep — you can send store requests only for a subset of submitted files, filtering them with your own personal heuristic, e.g. enforcing maximum file size or file type.

Autostore without a Server

But what if you don’t have a back end, or what if there’s no way to make a server-side store request? That’s when “autostore” comes in handy.

In order to avoid the API request, it is paramount for automatic storing to be enabled both in project settings and in the widget. You already know how to toggle it for a project. In the widget, there is a setting that makes the widget upload files with a specially-crafted request. This request tells the Uploadcare server that incoming files should be automatically stored, but only if the project allows automatic storing.

The setting comes in two varieties. Global, for all widgets on a page:

UPLOADCARE_PUBLIC_KEY = 'your_public_key';
// ... other settings

Local, for a specific widget:

<input type="hidden" role="uploadcare-uploader" data-autostore>

To permit automatic storing on the server, the widget makes use of a common upload API request parameterUPLOADCARE_STORE. This parameter is supported by all Uploadcare methods of upload. When, in a given request, it’s set to anything but 0 (“zero”) and automatic storing is enabled in project settings, the server will store every file sent with such a request.

Some Uploadcare libraries implement this functionality in their upload interface.

To Autostore or Not

Whether you can or need to use the “autostore” feature depends on your needs, of course. Here are some good examples where automatic storing is useful:

  • Private application without a server or with restricted access to server code.
  • A front-end tool plugin, like our official CKEditor plugin.
  • Environments where an additional HTTP request during form submission results in unacceptable response time.

Alternatively, if there are much more files uploaded to your account than you actually need, you are better off doing store requests yourself.

Choose whatever suits your project best and let Uploadcare handle the rest.

Find the documentation here https://uploadcare.com/documentation/widget/#autostore

May 22, 2013

Using Uploadcare with Django

The most importang thing for Uploadcare is to make file uploading on the web easy. Everyone is used to the routine work required to allow users to upload their userpics or attach resumes: from installing image processing libraries to creating folders with permissions, from ensuring the server never goes down or runs out of space to enabling CDN. And features like the ability to use a picture from Facebook or manual cropping are even more cumbersome, which explains why we rarely see them at all. Uploadcare’s goal is to change the status quo.

A simple Uploadcare File Field can be added to an existing Django project in just a couple of simple steps, and once installed, your users will be able to see the progress of their upload, choose files from Google Drive or Instagram, and make changes to the form while files are uploading asynchornously.

Installing the Uploadcare library

Step one is installing a pyuploadcare package. This is done by using pip:

$ pip install pyuploadcare

You may find you need to use sudo (in which case, we recommend you try virtualenv instead).

Django settings

Open your settings.py and add a dictionary with your keys. If you don’t have an account yet, you can use the demo keys provided in the example. However, files on the demo account are regularly deleted, so create an account as soon as Uploadcare catches your fancy:

    # Don't forget to swithc to real keys when it gets serious!

    'pub_key': 'demopublickey',
    'secret': 'demoprivatekey',

Model Fields

Uploadcare field in Django admin

To attach Uploadcare files to a model, you can use a FileField or ModelField:

from django.db import models

from pyuploadcare.dj import FileField           # first line

class Candidate(models.Model):
    name = models.CharField(max_length=120)
    about = models.TextField()

    resume = FileField(blank=True, null=True)   # second line
    photo = ImageField(blank=True, null=True, manual_crop="")

    def __unicode__(self):
        return self.name

These fields operate by common Django rules. South migrations are supported.

ImageField requires an uploaded file to be an image. The optional parameter manual_crop, if used, enables a manual cropping tool: your user can select a part of an image he or she wants to use. If its value is an empty string, the user can select any part of an image; you can also use such values as "3:4" or "200x300" to set the exact proportions or dimensions of the resulting image. Consult widget documentation regarding setting up the manual crop function:

Manual crop

Non-admin forms

Obviously, you will want to use Uploadcare fields outside an admin. Non-admin operates just as well, however you have to remember to add{{ form.media }} in the <head> tag of your page:

Uploadcare field in the wild

Using the files

After the file is uploaded, it can now be used. If you simply need a download link, using your field will suffice:

<a href="{{ object.resume }}">Download resume</a>

You can also use our CDN modifiers. They work with any image uploaded to Uploadcare. If manual_crop is enabled, your modifiers are going to be applied to the image, cropped as specified during upload; otherwise, it retains its original properties:

photo = ImageField()

<img src="{{ object.photo }}">
    ñ original image
<img src="{{ object.photo }}-/scale_crop/200x300/center/">
    - original image, scaled down and cropped to fit to 200x300

photo = ImageField(manual_crop="")

<img src="{{ object.photo }}">
    - original image, cropped as specified during upload
<img src="{{ object.photo }}-/scale_crop/200x300/center/">
    - same as above, scaled down and cropped to fit to 200x300

photo = ImageField(manual_crop="2:3")

<img src="{{ object.photo }}">
    - original image, cropped as specified during upload, with proportions at 2:3
<img src="{{ object.photo }}-/scale_crop/200x300/center/">
    - same as above, scaled down to fit into 200x300. As proportions are 2:3, no cropping is required

photo = ImageField(manual_crop="200x300")

<img src="{{ object.photo }}">
    - original image, cropped as specified during upload, with dimensions at 200x300
<img src="{{ object.photo }}-/resize/100x/">
    - same as above, but scaled to half its size (100x150)

Migration of existing files to Uploadcare

If you already have a database of images, you will want to migrate them to Uploadcare. The simplest way to do this is to keep all the old files where they are, and to upload all the new files to Uploadcare. The Uploadcare uploading widget allows using arbitrary URLs as its values, making this option quite straighforward.

To set your Uploadcare field value as the URL of an old file, you can use the initial parameter of the Django form. It’s especially simple with Class-Based Views:

class CandidateUpdateView(UpdateView):
    model = Candidate
    success_url = '/'

    def get_initial(self):
        initial = super(CandidateUpdateView, self).get_initial()

        if self.object and self.object.photo_old and not self.object.photo:
            initial['photo'] = self.object.photo_old.url

        return initial

Now, as soon as the update page is opened, the old file will be uploaded to Uploadcare, allowing your users to check it out in our widget and replace or just re-crop it as they wish.

That’s it!

As you can see, with Uploadcare, adding and working with the file field is just as simple as with a CharField. We’re happy to help make you and your clients experience better. Try Uploadcare right now! And don’t forget to add our iOS library to your mobile app.

All code is available on GitHub: https://github.com/uploadcare/uc_django_tutorial

Apr 24, 2013

Image cropping for your web app in 20 minutes

Cropping from inside the browser is great: it’s intuitive and simpler than loading a dedicated image editor. You can crop profile photos, graphics for user profile backgrounds or headers, and any sort of gallery images.

However, adding crop functionality to your uploads or existing images is but another mundane task to deal with, eating up time better spent on new ideas. Try Googling javascript image crop right now. There will be 30+ solutions and even blog posts attempting to describe them as vaguely as possible. What’s worse, when you finally pick one that better suits your language and framework of choice, you’re confronted with a very specific API, so good luck integrating it into your existing code base.

Everything we do at Uploadcare is directed at combating the mundane. Amongst other things, we offer image crop as SaaS. It will work with any image you throw at us, as long as it has a public URL. You only have to take 4 easy steps and we’ll take care of the rest.


Step 1: Register an Uploadcare project

Visit our signup page and register in one easy step. You can use your GitHub or Google accounts for secure one-click sign in.

Upon signup you’ll be forwarded to your profile page with your starting information. Your Uploadcare public and private keys are listed in a large font - make a note of them for later.

Step 2: Choose a form for cropping

We’re going to need a form in your application we can then enhance with the cropping function, say, a profile edit form. You don’t need to enable file uploads (i.e. multipart data), as we simply need the source URL and can integrate cropping in any HTML form.

Step 3: Integrate Uploadcare

We provide a cropping widget served from CloudFlare CDN with guaranteed uptime. Of course you can also download it and serve from your own domain, if you wish to do so.

To apply the widget to your form, add this to the bottom of the <head> section:

<script>UPLOADCARE_PUBLIC_KEY = 'your_public_key';</script>
<script src="https://ucarecdn.com/widget/0.8.1/uploadcare/uploadcare-0.8.1.min.js"></script>

Next, place this tag anywhere on your form, where you’d like the cropping widget to appear.


Copy and paste this code, or create an input like this with your form helpers. Be sure to replace original_image_url with an actual URL of the image you’d like to crop.

Now your form should have a widget like this:

Widget goes here…

The cropped image will automatically be hosted on our CDN. The UUID of this image will be submitted with your form as the value of the input field you added (named your_form_field_name in the sample code above).

You can restrict the way cropping is done with the data-crop attribute, by specifying the desired aspect ratio, as well as the minimum and maximum size, by use of automatic scaling. These options are fully described in widget documentation.

Step 4: Accept the cropped image

In your form submission handle you should have received an UUID (mentioned above). This is the UUID of the cropped version of the image stored on our CDN. It has a publicly-accessible URL:


This is a permalink that can replace the original image URL, where 3addab78-6368-4c55-ac08-22412b6a2a4c is the UUID.

But the image is not automatically available at this URL after a user submits the form. You need to acknowledge that it should be made public, by sending an HTTP request:

POST /files/image_uuid/storage/ HTTP/1.1
Host: api.uploadcare.com
Authorization: Uploadcare.Simple your_public_key:your_private_key

It’s a simple POST with a special Authorization header. Of course image_uuid,your_public_key, and your_private_key should be replaced with their real values.

Alternatively, there are Uploadcare libraries for a number of programming languages and frameworks that will do this storage request for you.

That’s it!

You’ve just given your users the ability to crop images, and without breaking a sweat. Well done.

The widget you’ve seen is also open source. If you’re not satisfied with it out of the box, feel free to fork around it and change it to your liking. And we’re also always happy to receive pull requests.

« To the past Page 1 of 2
Uploadcare handles uploading, storage and processing files for you.