Cloudinary Blog

The power of ImageMagick with the speed and simplicity of Cloudinary

Use ImageMagick with Speed & Simplicity |  Cloudinary Blog

Most developers are familiar with ImageMagick, a very capable open source software suite that they can use to manage and manipulate images.

The functionality of ImageMagick is typically utilized from the command-line, but wrappers have been written for a wide selection of programming languages, making ImageMagick a very popular choice among developers.

Often programmers use ImageMagick for simple operations such as scaling or stretching an image to fit specific dimensions. But as we'll see in this post, there are many advanced techniques available, such as 'masking’, pixel 'blending' and others that enable you to achieve more complex and extremely useful effects.

In this post, I’ll share three examples of image manipulations using RMagick (a Ruby wrapper for ImageMagick). I will start with a sepia effect combined with an overlay image, and follow that with increasingly complex manipulations such as creating text textures and pixelating faces. For each of these examples, I’ll compare what it takes to address the same challenges using Cloudinary. With its cloud-based platform, Cloudinary eliminates the complexity of coding and the hassles associated with installation. Cloudinary also saves developers time, enabling them to leverage a single line of code to complete the image manipulations.

Dependencies and Installation

You can find the full source code for this blog post in Cloudinary’s official repository in Github. Installing the dependencies for the examples is not a trivial task, mostly because of OpenCV. But for simplicity’s sake, I’ve containerized both ImageMagick and OpenCV dependencies, so you only need to have Docker installed.

Example 1: Sepia effect with text overlay

The first example describes a common use case: Adding a photographer's name to the bottom right corner of an image.
To make the example more interesting, we first want to apply a sepia effect.
The final result should look something like this:

Sepia and Overlay

The ImageMagick way:

The example is built using two main methods:

  • add_author_to_image!, which receives a Magick::Image object and the author name and returns a new Magick::Image object that contains the resulting image - the original image with the author name overlay applied.
  • sepiatize_image!, which receives a Magick::Image object and returns the modified image object with the sepia effect applied.

First, let’s describe add_author_to_image!:
Using ImageMagick, I create a Draw object, which will enable me to put the text over the original image.
I also select the color “white”, “Arial” as the font, and choose my font size.

Copy to clipboard
text = Magick::Draw.new
text.fill = "white"
text.font_family = "Arial"
text.pointsize = 30
text.gravity = Magick::CenterGravity

The overlay image size should match the text dimensions, so I need to calculate the text dimensions before creating the overlay image:

Copy to clipboard
metrics = text.get_type_metrics(author)

I then create the overlay image and set its background color to a semi-transparent black to ensure that the text will be visible on top of any image.

Copy to clipboard
author_overlay = Magick::Image.new(metrics.width, metrics.height) {
  self.background_color = "#00000080"
}

Next, I draw the text over the the semi-transparent background.

Copy to clipboard
text.annotate(author_overlay, 0, 0, 0, 0, author)

Then I position the author overlay on top of the image:

I use the composite method to combine the two images in a certain way. The destination image is our input image. I have to tell ImageMagick that I want to position the author overlay in the “southeast” edge of the image. Magick::OverCompositeOp tells ImageMagick that the source image (author_overlay) should override the destination image (our input image) with the source image’s pixels, which makes the author name visible on top of the image.

Copy to clipboard
image.composite!(author_overlay, Magick::SouthEastGravity, Magick::OverCompositeOp)

The final step is destroying the author image object overlay. It’s important to clean up any temporary image objects. I don’t need the overlay anymore because I’ve combined the images and flattened them. Destroying an image object is done using the destroy! method:

Copy to clipboard
author_overlay.destroy!

What’s missing now is the sepia effect (applied by the sepiatize_image! method).
ImageMagick offers a method for setting sepia tone, so I chose the sepia level and set the desired effect.

Copy to clipboard
SEPIA_LEVEL = Magick::QuantumRange * 60 / 100
def sepiatize_image!(image)
  image.sepiatone(SEPIA_LEVEL)
end

After defining the two methods, we need to apply both operations on our original image and write the result to a file:

Copy to clipboard
add_author_to_image!(sepiatize_image!(source_image), author).write(dest)

Whew! I’m sweating a bit, but I managed to get the result I wanted.

The Cloudinary way:

If this is your first time using Cloudinary, you’ll need sign up for an account (start with a free one), and use the upload API to upload your image. You can use the https API with no installation required, or download and install the SDK for your favorite framework (a few quick configurations required).

Here’s how you would upload the yellow_tulip.png file to your account in the cloud using the Ruby SDK:`

Copy to clipboard
Cloudinary::Uploader.upload('yellow_tulip.png', :public_id => 'yellow_tulip')

Now, let’s see what it takes to deliver that image in sepia with the photographer’s name in the corner. Ready?

Ruby:
Copy to clipboard
cl_image_tag("yellow_tulip.png", :transformation=>[
  {:effect=>"sepia:60"},
  {:overlay=>{:font_family=>"Arial", :font_size=>30, :text=>"John%20Doe%20Photography%20%C2%AE"}, :color=>"white", :gravity=>"south_east", :background=>"#00000090"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("yellow_tulip.png", array("transformation"=>array(
  array("effect"=>"sepia:60"),
  array("overlay"=>array("font_family"=>"Arial", "font_size"=>30, "text"=>"John%20Doe%20Photography%20%C2%AE"), "color"=>"white", "gravity"=>"south_east", "background"=>"#00000090")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('yellow_tulip.png'))
  ->effect(Effect::sepia()->level(60))
  ->overlay(
      Overlay::source(Source::text('John Doe Photography ®', (new TextStyle('Arial', 30)))
        ->textColor(Color::WHITE)->backgroundColor(Color::rgb('00000090')))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::southEast()))
  ));
Python:
Copy to clipboard
CloudinaryImage("yellow_tulip.png").image(transformation=[
  {'effect': "sepia:60"},
  {'overlay': {'font_family': "Arial", 'font_size': 30, 'text': "John%20Doe%20Photography%20%C2%AE"}, 'color': "white", 'gravity': "south_east", 'background': "#00000090"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("yellow_tulip.png", {transformation: [
  {effect: "sepia:60"},
  {overlay: {font_family: "Arial", font_size: 30, text: "John%20Doe%20Photography%20%C2%AE"}, color: "white", gravity: "south_east", background: "#00000090"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("sepia:60").chain()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(30).text("John%20Doe%20Photography%20%C2%AE")).color("white").gravity("south_east").background("#00000090")).imageTag("yellow_tulip.png");
JS:
Copy to clipboard
cloudinary.imageTag('yellow_tulip.png', {transformation: [
  {effect: "sepia:60"},
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(30).text("John%20Doe%20Photography%20%C2%AE"), color: "white", gravity: "south_east", background: "#00000090"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("yellow_tulip.png", {transformation: [
  {effect: "sepia:60"},
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(30).text("John%20Doe%20Photography%20%C2%AE"), color: "white", gravity: "south_east", background: "#00000090"}
  ]})
React:
Copy to clipboard
<Image publicId="yellow_tulip.png" >
  <Transformation effect="sepia:60" />
  <Transformation overlay={{fontFamily: "Arial", fontSize: 30, text: "John%20Doe%20Photography%20%C2%AE"}} color="white" gravity="south_east" background="#00000090" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="yellow_tulip.png" >
  <cld-transformation effect="sepia:60" />
  <cld-transformation :overlay="{fontFamily: 'Arial', fontSize: 30, text: 'John%20Doe%20Photography%20%C2%AE'}" color="white" gravity="south_east" background="#00000090" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="yellow_tulip.png" >
  <cl-transformation effect="sepia:60">
  </cl-transformation>
  <cl-transformation overlay="text:Arial_30:John%20Doe%20Photography%20%C2%AE" color="white" gravity="south_east" background="#00000090">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("sepia:60").Chain()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(30).Text("John%20Doe%20Photography%20%C2%AE")).Color("white").Gravity("south_east").Background("#00000090")).BuildImageTag("yellow_tulip.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("sepia:60").chain()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(30).text("John%20Doe%20Photography%20%C2%AE")).color("white").gravity("south_east").background("#00000090")).generate("yellow_tulip.png");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setEffect("sepia:60").chain()
  .setOverlay("text:Arial_30:John%20Doe%20Photography%20%C2%AE").setColor("white").setGravity("south_east").setBackground("#00000090")).generate("yellow_tulip.png")!, cloudinary: cloudinary)

Done!

Example 2: Text Textures

In this example, which is a bit more complex than our first one, I will use our source image as a texture effect on specified text with a selected font, so that it will look something like this:

Text Textures

The ImageMagick way:

I will employ the concept of masking in this example.
Let's create a 'mask' image in the shape of our desired text and font. I do this using the create_text_mask method, which receives the text as a string and returns a 'mask' Image object.
The following is a short walkthrough:

Like in the previous example, I create a Draw object, which is being used for the text.
I then add color, font family, size and weight, and get a type metric to create our ‘mask’ image object with the dimensions I calculated.

Then I create a new Image object and set it's background to transparent:

Copy to clipboard
draw = Magick::Draw.new
draw.fill = "white"
draw.font_family = "Arial"
draw.pointsize = 100
draw.font_weight = Magick::BoldWeight
draw.gravity = Magick::CenterGravity
metrics = draw.get_type_metrics(text)
mask = Magick::Image.new(metrics.width, metrics.height) { self.background_color = "transparent" }

Like in the previous example, I use the draw object’s annotate method to actually draw the text over the image I’ve created.

Copy to clipboard
draw.annotate(mask, 0, 0, 0, 0, text)

The result is a semi transparent image having the text itself in fully opaque "white" and the rest - fully transparent.

Let's move to the cut_image_to_text! method which calls create_text_mask:
After creating the mask image by calling create_text_mask, using the composite method, I combine the 'mask' image and our input image, but this time relying on a different type of composite operator: CopyOpacityCompositeOp.
Doing this changes the opacity value of all pixels in our input image that are not part of the text letters region, to fully transparent. This hides the pixels and results in a texture effect over the fonts:

Copy to clipboard
image.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)

Next, I have to clean up by destroying the mask image, which isn't needed anymore.

Copy to clipboard
mask.destroy!

Then I trim the remaining transparent border and tighten up the image to the text itself.

Copy to clipboard
image.trim!

At this point I’m almost done, but there’s one last thing to take care of.
A lot of formats – like JPEG – don’t have an alpha channel to support opacity. So, if you export the image now in one of those non-alpha formats, you’ll see the original image since all 'hidden' and 'fully transparent' pixels from our last step will not preserve their transparency. As a result, I’ll need to turn all transparent pixels to “opaque white”, which will make sure I get a uniform result no matter what the desired format is. This will be done using the simple opacify! method.

Here I set the background color to white:

Copy to clipboard
opacified = Magick::Image.new(image.columns, image.rows) { self.background_color = "white" }

Then I put the cut-to-text image that I created in the previous step on top of the new image with the white background color. This causes all transparent pixels from before to turn white.

Copy to clipboard
opacified.composite!(image, Magick::CenterGravity, Magick::OverCompositeOp)

After defining the relevant methods, I apply them on the original image and write the result to a file:

Copy to clipboard
opacify!(cut_image_to_text!(source, text)).write(dest)

Impressive! We did it!

The Cloudinary way:

You’d think this example would take a bit more effort than the previous one, even in Cloudinary. But with a combination of text overlay capabilities and the built-in cutter flag, here’s all we need to do:

Ruby:
Copy to clipboard
cl_image_tag("yellow_tulip.png", :overlay=>{:font_family=>"Arial", :font_size=>100, :font_weight=>"bold", :text=>"Flowers"}, :flags=>"cutter")
PHP v1:
Copy to clipboard
cl_image_tag("yellow_tulip.png", array("overlay"=>array("font_family"=>"Arial", "font_size"=>100, "font_weight"=>"bold", "text"=>"Flowers"), "flags"=>"cutter"))
PHP v2:
Copy to clipboard
(new ImageTag('yellow_tulip.png'))
  ->reshape(
      Reshape::cutByImage(
          Source::text('Flowers', (new TextStyle('Arial', 100))
            ->fontWeight(FontWeight::bold())
      
      )));
Python:
Copy to clipboard
CloudinaryImage("yellow_tulip.png").image(overlay={'font_family': "Arial", 'font_size': 100, 'font_weight': "bold", 'text': "Flowers"}, flags="cutter")
Node.js:
Copy to clipboard
cloudinary.image("yellow_tulip.png", {overlay: {font_family: "Arial", font_size: 100, font_weight: "bold", text: "Flowers"}, flags: "cutter"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new TextLayer().fontFamily("Arial").fontSize(100).fontWeight("bold").text("Flowers")).flags("cutter")).imageTag("yellow_tulip.png");
JS:
Copy to clipboard
cloudinary.imageTag('yellow_tulip.png', {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(100).fontWeight("bold").text("Flowers"), flags: "cutter"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("yellow_tulip.png", {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(100).fontWeight("bold").text("Flowers"), flags: "cutter"})
React:
Copy to clipboard
<Image publicId="yellow_tulip.png" >
  <Transformation overlay={{fontFamily: "Arial", fontSize: 100, fontWeight: "bold", text: "Flowers"}} flags="cutter" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="yellow_tulip.png" >
  <cld-transformation :overlay="{fontFamily: 'Arial', fontSize: 100, fontWeight: 'bold', text: 'Flowers'}" flags="cutter" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="yellow_tulip.png" >
  <cl-transformation overlay="text:Arial_100_bold:Flowers" flags="cutter">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay(new TextLayer().FontFamily("Arial").FontSize(100).FontWeight("bold").Text("Flowers")).Flags("cutter")).BuildImageTag("yellow_tulip.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new TextLayer().fontFamily("Arial").fontSize(100).fontWeight("bold").text("Flowers")).flags("cutter")).generate("yellow_tulip.png");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setOverlay("text:Arial_100_bold:Flowers").setFlags("cutter")).generate("yellow_tulip.png")!, cloudinary: cloudinary)

Example 3: Pixelating Faces

For my last example, I will show how to combine face detection with a pixelation effect, which is really useful for hiding people’s identities in public photos. Here’s what our final image will look like:

Pixelating Faces

The ImageMagick way:

This example involves use of the OpenCV library and the ruby-opencv gem. My code in this example is written in a flexible way that enables easy swapping of the face detection part to any other library or implementation (modify the detect_faces method to one of your liking, but you must make sure it returns an array of regions).

First, let’s have a look at the transform_faces method.
I’m creating a Magick:Image object out of this file, which I took from the user’s input, similar to the way I’ve done in our first two examples.

Copy to clipboard
image = Magick::Image.read(image_file).first

Then I detect faces for the image file. This process, which is done outside of ImageMagick, returns a collection of face regions.

Copy to clipboard
detect_faces(image_file).each do |region|
  transform_region!(image, region, operation)
end

Next, for each region, I call transform_region! over the image object. The transform_region method has top_left and bottom_right attributes, each with an X,Y value. Here I crop a new image out of the original image at the exact region that was identified.

Copy to clipboard
cropped_region = image.crop(region.top_left.x, region.top_left.y, region.width, region.height)

Then I call a method for the operation that I want to do with this cropped region image.

Copy to clipboard
cropped_region = send("#{operation}_image!", cropped_region)

In the example code in the repository, I pick an operation called pixelate. However, you also could select “blur” if that treatment was preferred:

Copy to clipboard
PIXELATE_FACTOR = 5
def pixelate_image!(image)
  image.scale!(1 / PIXELATE_FACTOR.to_f).scale!(PIXELATE_FACTOR)
end

Back to transform_region!: I need to set the "transformed" region on top of the original image, using composite again at the X,Y position. After that is complete, I flatten the image and then clean it up by destroying the cropped image region.

Copy to clipboard
image.composite!(cropped_region, region.top_left.x, region.top_left.y, Magick::OverCompositeOp)
cropped_region.destroy!

Not bad, huh?

The Cloudinary way:

By now, you have probably come to expect that you can accomplish the same goal with Cloudinary in one line of code, right? Yup!

Cloudinary has a built-in automatic face detection mechanism that enables, among other things, quick pixelation (or blurring) of all faces in a photo:

Pixelating faces

Ruby:
Copy to clipboard
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", :type=>"fetch", :transformation=>[
  {:effect=>"pixelate_faces"},
  {:width=>500, :crop=>"scale"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", array("type"=>"fetch", "transformation"=>array(
  array("effect"=>"pixelate_faces"),
  array("width"=>500, "crop"=>"scale")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg'))
  ->effect(Effect::pixelate()->region(Region::faces()))
  ->resize(Resize::scale()->width(500))
  ->deliveryType('fetch');
Python:
Copy to clipboard
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg").image(type="fetch", transformation=[
  {'effect': "pixelate_faces"},
  {'width': 500, 'crop': "scale"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", {type: "fetch", transformation: [
  {effect: "pixelate_faces"},
  {width: 500, crop: "scale"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("pixelate_faces").chain()
  .width(500).crop("scale")).type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg', {type: "fetch", transformation: [
  {effect: "pixelate_faces"},
  {width: 500, crop: "scale"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", {type: "fetch", transformation: [
  {effect: "pixelate_faces"},
  {width: 500, crop: "scale"}
  ]})
React:
Copy to clipboard
<Image publicId="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <Transformation effect="pixelate_faces" />
  <Transformation width="500" crop="scale" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <cld-transformation effect="pixelate_faces" />
  <cld-transformation width="500" crop="scale" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <cl-transformation effect="pixelate_faces">
  </cl-transformation>
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("pixelate_faces").Chain()
  .Width(500).Crop("scale")).Action("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("pixelate_faces").chain()
  .width(500).crop("scale")).type("fetch").generate("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setType( "fetch").setTransformation(CLDTransformation()
  .setEffect("pixelate_faces").chain()
  .setWidth(500).setCrop("scale")).generate("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg")!, cloudinary: cloudinary)

Blurring faces

Ruby:
Copy to clipboard
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", :type=>"fetch", :transformation=>[
  {:effect=>"blur_faces"},
  {:width=>500, :crop=>"scale"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", array("type"=>"fetch", "transformation"=>array(
  array("effect"=>"blur_faces"),
  array("width"=>500, "crop"=>"scale")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg'))
  ->effect(Effect::blur()->region(Region::faces()))
  ->resize(Resize::scale()->width(500))
  ->deliveryType('fetch');
Python:
Copy to clipboard
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg").image(type="fetch", transformation=[
  {'effect': "blur_faces"},
  {'width': 500, 'crop': "scale"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", {type: "fetch", transformation: [
  {effect: "blur_faces"},
  {width: 500, crop: "scale"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("blur_faces").chain()
  .width(500).crop("scale")).type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg', {type: "fetch", transformation: [
  {effect: "blur_faces"},
  {width: 500, crop: "scale"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg", {type: "fetch", transformation: [
  {effect: "blur_faces"},
  {width: 500, crop: "scale"}
  ]})
React:
Copy to clipboard
<Image publicId="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <Transformation effect="blur_faces" />
  <Transformation width="500" crop="scale" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <cld-transformation effect="blur_faces" />
  <cld-transformation width="500" crop="scale" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg" type="fetch">
  <cl-transformation effect="blur_faces">
  </cl-transformation>
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("blur_faces").Chain()
  .Width(500).Crop("scale")).Action("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("blur_faces").chain()
  .width(500).crop("scale")).type("fetch").generate("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setType( "fetch").setTransformation(CLDTransformation()
  .setEffect("blur_faces").chain()
  .setWidth(500).setCrop("scale")).generate("http://upload.wikimedia.org/wikipedia/commons/4/45/Spain_national_football_team_Euro_2012_final.jpg")!, cloudinary: cloudinary)

Conclusion

ImageMagick is a flexible, capable, open source software suite that developers have used to manage and manipulate images for years. As we saw in this post, ImageMagick can be utilized to do so much more than simply resizing an image.

At Cloudinary, we make use of ImageMagick for a wide range of use cases, and it serves as one of the valuable tools in our toolbelt.

Cloudinary abstracts the complexities of image manipulation, storage, administration and delivery and provides developers with an easy-to-use, end-to-end, cloud-based solution. Cloudinary enables developers to focus on creating their apps and presenting the best images possible.

If you haven't tried Cloudinary yet, I invite you to test it out. Visit our website to sign up for a account

Recent Blog Posts

Generate Waveform Images from Audio with Cloudinary

This is a reposting of an article written by David Walsh. Check out his blog HERE!
I've been working a lot with visualizations lately, which is a far cry from your normal webpage element interaction coding; you need advanced geometry knowledge, render and performance knowledge, and much more. It's been a great learning experience but it can be challenging and isn't always an interest of all web developers. That's why we use apps and services specializing in complex tasks like Cloudinary: we need it done quickly and by a tool written by an expert.

Read more
Make All Images on Your Website Responsive in 3 Easy Steps

Images are crucial to website performance, but most still don't implement responsive images. It’s not just about fitting an image on the screen, but also making the the image size relatively rational to the device. The srcset and sizes options, which are your best hit are hard to implement. Cloudinary provides an easier way, which we will discuss in this article.

Read more

The Future of Audio and Video on the Web

By Prosper Otemuyiwa
The Future of Audio and Video on the Web

Web sites and platforms are becoming increasingly media-rich. Today, approximately 62 percent of internet traffic is made up of images, with audio and video constituting a growing percentage of the bytes.

Read more

Embed Images in Email Campaigns at Scale

By Sourav Kundu
Embed Images in Email Campaigns at Scale

tl;dr

Cloudinary is a powerful image hosting solution for email marketing campaigns of any size. With features such as advanced image optimization and on-the-fly image transformation, backed by a global CDN, Cloudinary provides the base for a seamless user experience in your email campaigns leading to increased conversion and performance.

Read more
Build the Back-End For Your Own Instagram-style App with Cloudinary

Github Repo

Managing media files (processing, storage and manipulation) is one of the biggest challenges we encounter as practical developers. These challenges include:

A great service called Cloudinary can help us overcome many of these challenges. Together with Cloudinary, let's work on solutions to these challenges and hopefully have a simpler mental model towards media management.

Read more

Build A Miniflix in 10 Minutes

By Prosper Otemuyiwa
Build A Miniflix in 10 Minutes

Developers are constantly faced with challenges of building complex products every single day. And there are constraints on the time needed to build out the features of these products.

Engineering and Product managers want to beat deadlines for projects daily. CEOs want to roll out new products as fast as possible. Entrepreneurs need their MVPs like yesterday. With this in mind, what should developers do?

Read more