Cloudinary Blog

Uploading, Managing and Delivering PDFs

Uploading, Managing and Delivering PDFs With Cloudinary

The Portable Document Format (PDF) is a popular format developed by Adobe for delivering formatted text and images. A PDF file includes a complete description of all layout elements, including text, fonts, images and layers, ensuring that the file will look identical when opened on any device. The PDF format also has the big advantage of compressing high-quality files to a relatively small file size.

Cloudinary has built-in support for uploading, managing, converting, creating, analyzing and delivering PDF files, as well as third party add-ons for creating PDFs from Office documents, and extracting the text from PDFs. Furthermore, Cloudinary allows you to manage your PDFs like any other image file, benefiting from easy and simple transformations, fast CDN delivery, and more.

The following sections give a brief summary and example of each of the features available for working with PDfs as well as links to further information and details in the Cloudinary documentation.

Uploading PDF Files

Uploading PDFs to your Cloudinary account is really simple and straightforward. You can upload a PDF file using any of the options available for uploading files to your Cloudinary account. If you upload a PDF with multiple pages, the upload response will include a pages parameter indicating the number of pages within the file.

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("sample.pdf")
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("sample.pdf");
Python:
Copy to clipboard
cloudinary.uploader.upload("sample.pdf")
Node.js:
Copy to clipboard
cloudinary.v2.uploader.upload("sample.pdf", 
  function(error, result) {console.log(result, error); });
Java:
Copy to clipboard
cloudinary.uploader().upload("sample.pdf", ObjectUtils.emptyMap());
.NET:
Copy to clipboard
var uploadParams = new ImageUploadParams(){
  File = new FileDescription(@"sample.pdf")};
var uploadResult = cloudinary.Upload(uploadParams);
iOS:
Copy to clipboard
let params = CLDUploadRequestParams()
var mySig = MyFunction(params)  // your own function that returns a signature generated on your backend
params.setSignature(CLDSignature(signature: mySig.signature, timestamp: mySig.timestamp))
let request = cloudinary.createUploader().signedUpload(
  url: "sample.pdf", params: params)

If you need to determine the number of pages in a PDF that has already been uploaded to your account, you can use the Admin API resource method and include the pages parameter set to 'true'. For example:

Ruby:
Copy to clipboard
Cloudinary::Api.resource('sample_pdf',
  :pages => true)
PHP:
Copy to clipboard
$api->resource("sample",
  array(
    "pages" => TRUE));
Python:
Copy to clipboard
cloudinary.api.resource("sample_pdf",
  pages = True)
Node.js:
Copy to clipboard
cloudinary.v2.api.resource('sample_pdf', 
  { pages: true },
  function(error, result) {console.log(result, error); });
Java:
Copy to clipboard
api.resource("sample_pdf", 
  ObjectUtils.asMap(
    "pages", true ));
.NET:
Copy to clipboard
var getResource = new GetResourceParams("sample_pdf"){
  Pages = true};
var info = cloudinary.GetResource(getResource);
cURL:
Copy to clipboard
curl \
  -d "pages=1" \
  https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<cloud_name>/resources/image/upload/sample_pdf
CLI:
Copy to clipboard
cld admin resource sample_pdf pages=true

Delivering PDF Files

Cloudinary treats PDF files the same as any other image file. This is a great feature, as it means you can upload PDF files and then deliver them using a standard Cloudinary dynamic URL, for example:

Copy to clipboard
https://res.cloudinary.com/demo/image/upload/example_pdf.pdf

Important
In our efforts to make sure no malicious files are distributed through Cloudinary, free customers can’t deliver files in the PDF format by default. Please contact support if you want to enable this feature for your account.

Delivering the PDF in a different image format is as simple as changing the file extension to the desired format. This will deliver the first page of the PDF by default, but you can use the page parameter (pg in URLs) to select a different page. You can also use any other image transformation to deliver the new file, bringing Cloudinary’s advanced image transformation functionality to your PDFs.

For example, cropping out a specific 300x300 square from the second page, with rounded corners and a black background:

Ruby:
Copy to clipboard
cl_image_tag("multi_page_pdf.png", :transformation=>[
  {:page=>2},
  {:width=>300, :height=>300, :gravity=>"north", :y=>270, :crop=>"crop"},
  {:radius=>"max"},
  {:background=>"black"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("multi_page_pdf.png", array("transformation"=>array(
  array("page"=>2),
  array("width"=>300, "height"=>300, "gravity"=>"north", "y"=>270, "crop"=>"crop"),
  array("radius"=>"max"),
  array("background"=>"black")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('multi_page_pdf.png'))
  ->extract(Extract::getPage()->byNumber(2))
  ->resize(Resize::crop()->width(300)->height(300)
    ->gravity(Gravity::compass(Compass::north()))
    ->y(270))
  ->roundCorners(RoundCorners::max())
  ->backgroundColor(Color::BLACK);
Python:
Copy to clipboard
CloudinaryImage("multi_page_pdf.png").image(transformation=[
  {'page': 2},
  {'width': 300, 'height': 300, 'gravity': "north", 'y': 270, 'crop': "crop"},
  {'radius': "max"},
  {'background': "black"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("multi_page_pdf.png", {transformation: [
  {page: 2},
  {width: 300, height: 300, gravity: "north", y: 270, crop: "crop"},
  {radius: "max"},
  {background: "black"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .page(2).chain()
  .width(300).height(300).gravity("north").y(270).crop("crop").chain()
  .radius("max").chain()
  .background("black")).imageTag("multi_page_pdf.png");
JS:
Copy to clipboard
cloudinary.imageTag('multi_page_pdf.png', {transformation: [
  {page: 2},
  {width: 300, height: 300, gravity: "north", y: 270, crop: "crop"},
  {radius: "max"},
  {background: "black"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("multi_page_pdf.png", {transformation: [
  {page: 2},
  {width: 300, height: 300, gravity: "north", y: 270, crop: "crop"},
  {radius: "max"},
  {background: "black"}
  ]})
React:
Copy to clipboard
<Image publicId="multi_page_pdf.png" >
  <Transformation page="2" />
  <Transformation width="300" height="300" gravity="north" y="270" crop="crop" />
  <Transformation radius="max" />
  <Transformation background="black" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="multi_page_pdf.png" >
  <cld-transformation page="2" />
  <cld-transformation width="300" height="300" gravity="north" y="270" crop="crop" />
  <cld-transformation radius="max" />
  <cld-transformation background="black" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="multi_page_pdf.png" >
  <cl-transformation page="2">
  </cl-transformation>
  <cl-transformation width="300" height="300" gravity="north" y="270" crop="crop">
  </cl-transformation>
  <cl-transformation radius="max">
  </cl-transformation>
  <cl-transformation background="black">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Page(2).Chain()
  .Width(300).Height(300).Gravity("north").Y(270).Crop("crop").Chain()
  .Radius("max").Chain()
  .Background("black")).BuildImageTag("multi_page_pdf.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .page(2).chain()
  .width(300).height(300).gravity("north").y(270).crop("crop").chain()
  .radius("max").chain()
  .background("black")).generate("multi_page_pdf.png");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setPage(2).chain()
  .setWidth(300).setHeight(300).setGravity("north").setY(270).setCrop("crop").chain()
  .setRadius("max").chain()
  .setBackground("black")).generate("multi_page_pdf.png")!, cloudinary: cloudinary)
pdf as image + transformations

Creating PDF Files

PDFs can also be a great way to organize your content and deliver a set of images in a single file. Cloudinary provides the multi method for creating a PDF file from images in your Cloudinay account that all have the same tag. All the images are then merged into a single multi-page PDF, where each image is a separate page, and they are ordered alphanumerically by their public ID. If you want the images to be included in a specific order, make sure to rename them accordingly (e.g., 01img, 02img, etc). The multi method is also useful for creating animated images, so make sure to specify the format as pdf.

For example, to create a PDF file from a all images that have the tag "animal", and limit all images to a size of 400x600:

Ruby:
Copy to clipboard
Cloudinary::Uploader.multi("animal", :
  format => "pdf", :
  transformation => {
    :width => 400, 
    :height => 6--,
    :crop => "limit"})
PHP:
Copy to clipboard
\Cloudinary\Uploader::multi("animal", 
  array(
    "format"=>"pdf", 
    "transformation"=>array(
      "width"=>400,
      "height"=>600,
      "crop"=>"limit")));
Python:
Copy to clipboard
cloudinary.uploader.multi("animal", 
  format = "pdf",   
  transformation={
    "width": 400, 
    "Height": 600,
    "crop": "limit"})
Node.js:
Copy to clipboard
cloudinary.v2.uploader.multi("animal",
  { format: "pdf",
    transformation: {
      width: 400,
      Height: 600
      crop: "limit"}}, 
  function(error,result) {console.log(result, error) });
Java:
Copy to clipboard
cloudinary.uploader().multi("animal", 
  ObjectUtils.asMap(
    "format", "pdf"
    "transformation", new Transformation()
       .width(400).height(600).crop("limit"));
.NET:
Copy to clipboard
var multiParams = new MultiParams("animal"){
  Format = "pdf", 
  Transformation = new Transformation()
   .Width(400).Height(600).Crop("limit")};
var multiResult = cloudinary.Multi(multiParams);
cURL:
Copy to clipboard
curl https://api.cloudinary.com/v1_1/demo/image/multi -X POST --data 'tag=animal&format=pdf&transformation=w_400,h_600,c_limit&timestamp=173719931&api_key=1252464226&signature=a13282348f85a22868af'

Creating PDFs From Office Documents

If you need a way to automatically convert your Office documents, spreadsheets and presentations to PDF documents, Cloudinary offers the Aspose's document conversion add-on.

You start by uploading the Office file to your Cloudinary account as a raw file and adding the raw_convert parameter with a value of 'aspose'.

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("sample.docx",
  :public_id => "sample_doc.docx",
  :resource_type => 'raw', 
  :raw_convert => 'aspose')
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("sample.docx",
  array(
   "public_id" => "sample_doc.docx",
   "resource_type" => "raw",
   "raw_convert" => "aspose"));
Python:
Copy to clipboard
cloudinary.uploader.upload("sample.docx",
  public_id = "sample_doc.docx",
  resource_type = "raw",
  raw_convert = "aspose")
Node.js:
Copy to clipboard
cloudinary.v2.uploader.upload("sample.docx",
  { public_id: "sample_doc.docx",
    resource_type: "raw",
    raw_convert: "aspose" },
  function(error, result){console.log(result);});
Java:
Copy to clipboard
cloudinary.uploader().upload("sample.docx", 
  ObjectUtils.asMap(
    "public_id", "sample_doc.docx",
    "resource_type", "raw",
    "raw_convert", "aspose"));
.NET:
Copy to clipboard
var uploadParams = new RawUploadParams(){
  File = new FileDescription(@"sample.docx"),
  PublicId = "sample_doc.docx",
  RawConvert = "aspose"};
var uploadResult = cloudinary.Upload(uploadParams);

Once the conversion has finished, a PDF with the same public ID is added to your Cloudinary account as type image (the original still exists as type raw). In the example above, a new image (PDF) is added called sample_doc.docx, and can be delivered and/or transformed as any other PDF uploaded to your account.

Extract Text From a PDF

Analyzing the context of a PDF file can be useful in a number of scenarios. It may be as simple as knowing if the file has any text at all, finding out what the text contains and tagging the file appropriately, or even to redact or blur specific text in the file. Cloudinary provides the OCR Text Detection and Extraction add-on for extracting all the text from a PDF, and it includes a summary of the text, coordinates of the captured text, as well as every individual text element. To request the detected text, add the ocr parameter with a value of adv_ocr:document. For example, when using the upload method:

Ruby:
Copy to clipboard
Cloudinary::Uploader.upload("sample.pdf",  
  :ocr => "adv_ocr")
PHP:
Copy to clipboard
\Cloudinary\Uploader::upload("sample.pdf", 
  array("ocr" => "adv_ocr"));
Python:
Copy to clipboard
cloudinary.uploader.upload("sample.pdf",
  ocr = "adv_ocr")
Node.js:
Copy to clipboard
cloudinary.v2.uploader.upload("sample.pdf", 
  { ocr: "adv_ocr" },
  function(error, result) {console.log(result); });
Java:
Copy to clipboard
cloudinary.uploader().upload("sample.pdf", 
  ObjectUtils.asMap("ocr", "adv_ocr"));
.NET:
Copy to clipboard
var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"sample.pdf"),
  Ocr = "adv_ocr"
};
var uploadResult = cloudinary.Upload(uploadParams);

Rasterize a PDF

Rasterizing a PDF is useful if you still want to deliver a PDF file, but also want to resize the file, or maybe add an overlay. Rasterization reduces the PDF to a single flat pixelated layer (as opposed to vector based multiple layers). Simply add the rasterize flag to the dynamic URL (fl_rasterize) and add any resizing or overlays as desired. The following example rasterizes a PDF, scales it down to a width of 800 pixels and adds the Cloudinary icon to the top right corner of each page:

Ruby:
Copy to clipboard
cl_image_tag("multi_page_pdf.pdf", :transformation=>[
  {:flags=>"rasterize"},
  {:width=>800, :crop=>"scale"},
  {:overlay=>"cloudinary_icon", :gravity=>"north_east", :width=>100}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("multi_page_pdf.pdf", array("transformation"=>array(
  array("flags"=>"rasterize"),
  array("width"=>800, "crop"=>"scale"),
  array("overlay"=>"cloudinary_icon", "gravity"=>"north_east", "width"=>100)
  )))
PHP v2:
Copy to clipboard
(new ImageTag('multi_page_pdf.pdf'))
  ->addFlag('rasterize')->resize(Resize::scale()->width(800))
  ->overlay(
      Overlay::source(Source::image('cloudinary_icon')
        ->transformation((new ImageTransformation())
          ->resize(Resize::scale()->width(100))))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northEast()))
  ));
Python:
Copy to clipboard
CloudinaryImage("multi_page_pdf.pdf").image(transformation=[
  {'flags': "rasterize"},
  {'width': 800, 'crop': "scale"},
  {'overlay': "cloudinary_icon", 'gravity': "north_east", 'width': 100}
  ])
Node.js:
Copy to clipboard
cloudinary.image("multi_page_pdf.pdf", {transformation: [
  {flags: "rasterize"},
  {width: 800, crop: "scale"},
  {overlay: "cloudinary_icon", gravity: "north_east", width: 100}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .flags("rasterize").chain()
  .width(800).crop("scale").chain()
  .overlay(new Layer().publicId("cloudinary_icon")).gravity("north_east").width(100)).imageTag("multi_page_pdf.pdf");
JS:
Copy to clipboard
cloudinary.imageTag('multi_page_pdf.pdf', {transformation: [
  {flags: "rasterize"},
  {width: 800, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), gravity: "north_east", width: 100}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("multi_page_pdf.pdf", {transformation: [
  {flags: "rasterize"},
  {width: 800, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("cloudinary_icon"), gravity: "north_east", width: 100}
  ]})
React:
Copy to clipboard
<Image publicId="multi_page_pdf.pdf" >
  <Transformation flags="rasterize" />
  <Transformation width="800" crop="scale" />
  <Transformation overlay="cloudinary_icon" gravity="north_east" width="100" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="multi_page_pdf.pdf" >
  <cld-transformation flags="rasterize" />
  <cld-transformation width="800" crop="scale" />
  <cld-transformation :overlay="cloudinary_icon" gravity="north_east" width="100" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="multi_page_pdf.pdf" >
  <cl-transformation flags="rasterize">
  </cl-transformation>
  <cl-transformation width="800" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="cloudinary_icon" gravity="north_east" width="100">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Flags("rasterize").Chain()
  .Width(800).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("cloudinary_icon")).Gravity("north_east").Width(100)).BuildImageTag("multi_page_pdf.pdf")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .flags("rasterize").chain()
  .width(800).crop("scale").chain()
  .overlay(new Layer().publicId("cloudinary_icon")).gravity("north_east").width(100)).generate("multi_page_pdf.pdf");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setFlags("rasterize").chain()
  .setWidth(800).setCrop("scale").chain()
  .setOverlay("cloudinary_icon").setGravity("north_east").setWidth(100)).generate("multi_page_pdf.pdf")!, cloudinary: cloudinary)

Summing Up

Cloudinary has some great features that make working with PDF files simple and easy, with multiple options for uploading PDFs to your account, extensive transformations available, fast CDN delivery, and multiple methods for managing and extracting useful information from your files. And since it's a simple matter to convert PDF files to other image formats, they can also benefit from the multitude of transformations effects available to all images. Make sure to also check the Cloudinary documentation for more details, and if you don't have a Cloudinary account, make sure to sign up for your free account now and try it out.

Recent Blog Posts

Our $2B Valuation

By
Blackstone Growth Invests in Cloudinary

When we started our journey in 2012, we were looking to improve our lives as developers by making it easier for us to handle the arduous tasks of handling images and videos in our code. That initial line of developer code has evolved into a full suite of media experience solutions driven by a mission that gradually revealed itself over the course of the past 10 years: help companies unleash the full potential of their media to create the most engaging visual experiences.

Read more
Direct-to-Consumer E-Commerce Requires Compelling Visual Experiences

When brands like you adopt a direct–to-consumer (DTC) e-commerce approach with no involvement of retailers or marketplaces, you gain direct and timely insight into evolving shopping behaviors. Accordingly, you can accommodate shoppers’ preferences by continually adjusting your product offering and interspersing the shopping journey with moments of excitement and intrigue. Opportunities abound for you to cultivate engaging customer relationships.

Read more
Automatically Translating Videos for an International Audience

No matter your business focus—public service, B2B integration, recruitment—multimedia, in particular video, is remarkably effective in communicating with the audience. Before, making video accessible to diverse viewers involved tasks galore, such as eliciting the service of production studios to manually dub, transcribe, and add subtitles. Those operations were costly and slow, especially for globally destined content.

Read more
Cloudinary Helps Minted Manage Its Image-Generation Pipeline at Scale

Shoppers return time and again to Minted’s global online community of independent artists and designers because they know they can count on unique, statement-making products of the highest quality there. Concurrently, the visual imagery on Minted.com must do justice to the designs into which the creators have poured their hearts and souls. For Minted’s VP of Engineering David Lien, “Because we are a premium brand, we need to ensure that every single one of our product images matches the selected configuration exactly. For example, if you pick an 18x24 art print on blue canvas, we will show that exact combination on the hero images in the PDF.”

Read more
Highlights on ImageCon 2021 and a Preview of ImageCon 2022

New year, same trend! Visual media will continue to play a monumental role in driving online conversions. To keep up with visual-experience trends and best practices, Cloudinary holds an annual conference called ImageCon, a one-of-a-kind event that helps attendees create the most engaging visual experiences possible.

Read more