Cloudinary Blog

Relive the Glory of Japanese Fighting Baseball With faker.js and Cloudinary

By
Generate Names With faker.js and Convert Them to Graphics With Cloudinary

The year was 1994. South Africa held its first fully representative democratic election, Netscape Navigator became the first commercially successful web browser. Coconuts Japan re-released EA Sports' MLBPA Baseball video game under the perhaps surprising title Fighting Baseball. Unlike MLBPA Baseball, which was licensed by the Major League Baseball (MLB), Fighting Baseball could not infringe on MLB trademarks, reference the National League or American League by name, or adopt actual team or player names.

To get around that limitation, the team invented an entire league's worth of fake American names. That’s thanks to a simple procedure concocted by some clever internet sleuths: Take a player's last name, change a letter or two, and pair that last name with another player's first name, which was occasionally edited in a similar way.

The results were simply beautiful with long-lasting appeal. After all, who wouldn’t want to play baseball with Todd Bonzalez, Bobson Dugnutt, and Sleve McDichael?

That was then; this is now. In the last 25 years, the ability to generate an unending amount of randomness has taken off at top speed, and programmatically producing fake names in a like manner is achievable. Once a list is in hand, it’s a breeze to leverage Cloudinary to turn it into a graphic that fits right into the game.

Even better, we can do all the randomization on the front end and generate images with front-end calls to Cloudinary. The result is a Jamstack app that requires no server management. This post shines a light on the process.

Faking Names With faker.js

First, generate template names with the faker.js JavaScript library, which offers many utilities for spawning fake data: names, dates, addresses, passwords, vehicles, bitcoin addresses. Here, we'll take advantage of faker's name-generating capabilities. See the steps below.

  1. initialize with a locale and a seed to ensure that the results are deterministic based on the URL:

    Copy to clipboard
    const faker = window.faker;
    faker.locale = "en_US";
    // getParameterByName is a utility function retrieving the seed from the URL.
    let seed = parseInt(getParameterByName("seed"));
    if (seed && !isNaN(seed)) {
    faker.seed(seed);
    }
  2. Generate names of 16 characters maximum so that the names would display properly in the image.

    Copy to clipboard
    do {
    firstName = faker.name.firstName(0);
    lastName = faker.name.lastName();
    name = `${firstName} ${lastName}`;
    } while (name.length > 16)
  3. Arbitrarily replace one or two characters of the last name with other characters for a touch of randomness. The scramble function picks the letters and passes them to the validMoves function to determine an appropriate replacement.

    Copy to clipboard
    function validMoves(letter) {
    if (letter.toUpperCase() == "Y") return; // Y is tricky, just don't mess with it.
    const hPreceders = ["c", "s", "t"];
    const consonants = "bdfghjklmnpqrvwxz".split("");
    const vowels = "aeiou".split("");
    let toReturn;
    if (hPreceders.includes(letter.toLowerCase())) {
    return hPreceders;
    } else if (consonants.includes(letter.toLowerCase())) {
    return consonants;
    } else {
    return vowels;
    }
    }

    We always return the same class of letter: H preceder, consonant, or vowel.

  4. Perform a similar replacement on the first name about 20% of the time, matching the apparent trend in Fighting Baseball.

That's it. A new name is now available, and we're ready to generate images.

Generating Images With Cloudinary

Start with

Ruby:
Copy to clipboard
cl_image_tag("bobson.jpg")
PHP v1:
Copy to clipboard
cl_image_tag("bobson.jpg")
PHP v2:
Copy to clipboard
(new ImageTag('bobson.jpg'));
Python:
Copy to clipboard
CloudinaryImage("bobson.jpg").image()
Node.js:
Copy to clipboard
cloudinary.image("bobson.jpg")
Java:
Copy to clipboard
cloudinary.url().imageTag("bobson.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('bobson.jpg').toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bobson.jpg")
React:
Copy to clipboard
<Image publicId="bobson.jpg" >

</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="bobson.jpg" >

</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="bobson.jpg" >

</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.BuildImageTag("bobson.jpg")
Android:
Copy to clipboard
MediaManager.get().url().generate("bobson.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().generate("bobson.jpg")!, cloudinary: cloudinary)
and layer on names. Cloudinary's transformation feature for text layers is the perfect tool for the job. We can specify position, font, size, color, and text transformations, along with, of course, the text itself.

Here's the transformation for the first player, Gbant Nolav (originally Grant Nolan):

Copy to clipboard
co_rgb:edeae5,l_text:Press Start 2P_16:GBANT%2520NOLAV/co_rgb:000000,e_shadow:5,x_2,y_2/fl_layer_apply,g_north_west,x_38,y_30

The font Press Start 2P, available on Google Fonts, looks reasonably similar to the original in the game, and Cloudinary supports text overlays with any Google font out of the box. Also added is a black shadow with the e_shadow effect.

Finally, place the text with a northwest gravity, as well as specific x and y coordinates to offset from the corner. Here is the result:

Ruby:
Copy to clipboard
cl_image_tag("bobson.jpg", :transformation=>[
  {:color=>"#edeae5", :overlay=>{:font_family=>"P", :font_size=>16, :text=>"GBANT%2520NOLAV"}},
  {:color=>"#000000", :effect=>"shadow:5", :x=>2, :y=>2},
  {:flags=>"layer_apply", :gravity=>"north_west", :x=>38, :y=>30}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("bobson.jpg", array("transformation"=>array(
  array("color"=>"#edeae5", "overlay"=>array("font_family"=>"P", "font_size"=>16, "text"=>"GBANT%2520NOLAV")),
  array("color"=>"#000000", "effect"=>"shadow:5", "x"=>2, "y"=>2),
  array("flags"=>"layer_apply", "gravity"=>"north_west", "x"=>38, "y"=>30)
  )))
PHP v2:
Copy to clipboard
(new ImageTag('bobson.jpg'))
  ->overlay(
      Overlay::source(Source::text('GBANT%20NOLAV', (new TextStyle('Press Start 2P', 16)))
        ->textColor(Color::rgb('edeae5'))
        ->transformation((new ImageTransformation())
          ->effect(Effect::shadow()->strength(5)
            ->color(Color::rgb('000000'))
            ->offsetX(2)->offsetY(2))))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northWest()))
        ->offsetX(38)->offsetY(30)
  ));
Python:
Copy to clipboard
CloudinaryImage("bobson.jpg").image(transformation=[
  {'color': "#edeae5", 'overlay': {'font_family': "P", 'font_size': 16, 'text': "GBANT%2520NOLAV"}},
  {'color': "#000000", 'effect': "shadow:5", 'x': 2, 'y': 2},
  {'flags': "layer_apply", 'gravity': "north_west", 'x': 38, 'y': 30}
  ])
Node.js:
Copy to clipboard
cloudinary.image("bobson.jpg", {transformation: [
  {color: "#edeae5", overlay: {font_family: "P", font_size: 16, text: "GBANT%2520NOLAV"}},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(30)).imageTag("bobson.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('bobson.jpg', {transformation: [
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bobson.jpg", {transformation: [
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30}
  ]})
React:
Copy to clipboard
<Image publicId="bobson.jpg" >
  <Transformation color="#edeae5" overlay={{fontFamily: "P", fontSize: 16, text: "GBANT%2520NOLAV"}} />
  <Transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <Transformation flags="layer_apply" gravity="north_west" x="38" y="30" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="bobson.jpg" >
  <cld-transformation color="#edeae5" :overlay="{fontFamily: 'P', fontSize: 16, text: 'GBANT%2520NOLAV'}" />
  <cld-transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <cld-transformation flags="layer_apply" gravity="north_west" x="38" y="30" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="bobson.jpg" >
  <cl-transformation color="#edeae5" overlay="text:Press%20Start%202P_16:GBANT%2520NOLAV">
  </cl-transformation>
  <cl-transformation color="#000000" effect="shadow:5" x="2" y="2">
  </cl-transformation>
  <cl-transformation flags="layer_apply" gravity="north_west" x="38" y="30">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Color("#edeae5").Overlay(new TextLayer().FontFamily("P").FontSize(16).Text("GBANT%2520NOLAV")).Chain()
  .Color("#000000").Effect("shadow:5").X(2).Y(2).Chain()
  .Flags("layer_apply").Gravity("north_west").X(38).Y(30)).BuildImageTag("bobson.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(30)).generate("bobson.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setColor("#edeae5").setOverlay("text:Press%20Start%202P_16:GBANT%2520NOLAV").chain()
  .setColor("#000000").setEffect("shadow:5").setX(2).setY(2).chain()
  .setFlags("layer_apply").setGravity("north_west").setX(38).setY(30)).generate("bobson.jpg")!, cloudinary: cloudinary)
Board with one name

To add another name, Troy Orl (originally Troy Orn), with a similar transformation:

Copy to clipboard
co_rgb:edeae5,l_text:Press Start 2P_16:TROY%2520ORL/co_rgb:000000,e_shadow:5,x_2,y_2/fl_layer_apply,g_north_west,x_38,y_50

The result:

Ruby:
Copy to clipboard
cl_image_tag("bobson.jpg", :transformation=>[
  {:color=>"#edeae5", :overlay=>{:font_family=>"P", :font_size=>16, :text=>"GBANT%2520NOLAV"}},
  {:color=>"#000000", :effect=>"shadow:5", :x=>2, :y=>2},
  {:flags=>"layer_apply", :gravity=>"north_west", :x=>38, :y=>30},
  {:color=>"#edeae5", :overlay=>{:font_family=>"P", :font_size=>16, :text=>"TROY%2520ORL"}},
  {:color=>"#000000", :effect=>"shadow:5", :x=>2, :y=>2},
  {:flags=>"layer_apply", :gravity=>"north_west", :x=>38, :y=>50}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("bobson.jpg", array("transformation"=>array(
  array("color"=>"#edeae5", "overlay"=>array("font_family"=>"P", "font_size"=>16, "text"=>"GBANT%2520NOLAV")),
  array("color"=>"#000000", "effect"=>"shadow:5", "x"=>2, "y"=>2),
  array("flags"=>"layer_apply", "gravity"=>"north_west", "x"=>38, "y"=>30),
  array("color"=>"#edeae5", "overlay"=>array("font_family"=>"P", "font_size"=>16, "text"=>"TROY%2520ORL")),
  array("color"=>"#000000", "effect"=>"shadow:5", "x"=>2, "y"=>2),
  array("flags"=>"layer_apply", "gravity"=>"north_west", "x"=>38, "y"=>50)
  )))
PHP v2:
Copy to clipboard
(new ImageTag('bobson.jpg'))
  ->overlay(
      Overlay::source(Source::text('GBANT%20NOLAV', (new TextStyle('Press Start 2P', 16)))
        ->textColor(Color::rgb('edeae5'))
        ->transformation((new ImageTransformation())
          ->effect(Effect::shadow()->strength(5)
            ->color(Color::rgb('000000'))
            ->offsetX(2)->offsetY(2))))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northWest()))
        ->offsetX(38)->offsetY(30)))
    ->overlay(
        Overlay::source(Source::text('TROY%20ORL', (new TextStyle('Press Start 2P', 16)))
          ->textColor(Color::rgb('edeae5'))
          ->transformation((new ImageTransformation())
            ->effect(Effect::shadow()->strength(5)
              ->color(Color::rgb('000000'))
              ->offsetX(2)->offsetY(2))))
        ->position((new Position())
          ->gravity(Gravity::compass(Compass::northWest()))
          ->offsetX(38)->offsetY(50)
      
    ));
Python:
Copy to clipboard
CloudinaryImage("bobson.jpg").image(transformation=[
  {'color': "#edeae5", 'overlay': {'font_family': "P", 'font_size': 16, 'text': "GBANT%2520NOLAV"}},
  {'color': "#000000", 'effect': "shadow:5", 'x': 2, 'y': 2},
  {'flags': "layer_apply", 'gravity': "north_west", 'x': 38, 'y': 30},
  {'color': "#edeae5", 'overlay': {'font_family': "P", 'font_size': 16, 'text': "TROY%2520ORL"}},
  {'color': "#000000", 'effect': "shadow:5", 'x': 2, 'y': 2},
  {'flags': "layer_apply", 'gravity': "north_west", 'x': 38, 'y': 50}
  ])
Node.js:
Copy to clipboard
cloudinary.image("bobson.jpg", {transformation: [
  {color: "#edeae5", overlay: {font_family: "P", font_size: 16, text: "GBANT%2520NOLAV"}},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30},
  {color: "#edeae5", overlay: {font_family: "P", font_size: 16, text: "TROY%2520ORL"}},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 50}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(30).chain()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("TROY%2520ORL")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(50)).imageTag("bobson.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('bobson.jpg', {transformation: [
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30},
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("TROY%2520ORL")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 50}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bobson.jpg", {transformation: [
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 30},
  {color: "#edeae5", overlay: new cloudinary.TextLayer().fontFamily("P").fontSize(16).text("TROY%2520ORL")},
  {color: "#000000", effect: "shadow:5", x: 2, y: 2},
  {flags: "layer_apply", gravity: "north_west", x: 38, y: 50}
  ]})
React:
Copy to clipboard
<Image publicId="bobson.jpg" >
  <Transformation color="#edeae5" overlay={{fontFamily: "P", fontSize: 16, text: "GBANT%2520NOLAV"}} />
  <Transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <Transformation flags="layer_apply" gravity="north_west" x="38" y="30" />
  <Transformation color="#edeae5" overlay={{fontFamily: "P", fontSize: 16, text: "TROY%2520ORL"}} />
  <Transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <Transformation flags="layer_apply" gravity="north_west" x="38" y="50" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="bobson.jpg" >
  <cld-transformation color="#edeae5" :overlay="{fontFamily: 'P', fontSize: 16, text: 'GBANT%2520NOLAV'}" />
  <cld-transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <cld-transformation flags="layer_apply" gravity="north_west" x="38" y="30" />
  <cld-transformation color="#edeae5" :overlay="{fontFamily: 'P', fontSize: 16, text: 'TROY%2520ORL'}" />
  <cld-transformation color="#000000" effect="shadow:5" x="2" y="2" />
  <cld-transformation flags="layer_apply" gravity="north_west" x="38" y="50" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="bobson.jpg" >
  <cl-transformation color="#edeae5" overlay="text:Press%20Start%202P_16:GBANT%2520NOLAV">
  </cl-transformation>
  <cl-transformation color="#000000" effect="shadow:5" x="2" y="2">
  </cl-transformation>
  <cl-transformation flags="layer_apply" gravity="north_west" x="38" y="30">
  </cl-transformation>
  <cl-transformation color="#edeae5" overlay="text:Press%20Start%202P_16:TROY%2520ORL">
  </cl-transformation>
  <cl-transformation color="#000000" effect="shadow:5" x="2" y="2">
  </cl-transformation>
  <cl-transformation flags="layer_apply" gravity="north_west" x="38" y="50">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Color("#edeae5").Overlay(new TextLayer().FontFamily("P").FontSize(16).Text("GBANT%2520NOLAV")).Chain()
  .Color("#000000").Effect("shadow:5").X(2).Y(2).Chain()
  .Flags("layer_apply").Gravity("north_west").X(38).Y(30).Chain()
  .Color("#edeae5").Overlay(new TextLayer().FontFamily("P").FontSize(16).Text("TROY%2520ORL")).Chain()
  .Color("#000000").Effect("shadow:5").X(2).Y(2).Chain()
  .Flags("layer_apply").Gravity("north_west").X(38).Y(50)).BuildImageTag("bobson.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("GBANT%2520NOLAV")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(30).chain()
  .color("#edeae5").overlay(new TextLayer().fontFamily("P").fontSize(16).text("TROY%2520ORL")).chain()
  .color("#000000").effect("shadow:5").x(2).y(2).chain()
  .flags("layer_apply").gravity("north_west").x(38).y(50)).generate("bobson.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setColor("#edeae5").setOverlay("text:Press%20Start%202P_16:GBANT%2520NOLAV").chain()
  .setColor("#000000").setEffect("shadow:5").setX(2).setY(2).chain()
  .setFlags("layer_apply").setGravity("north_west").setX(38).setY(30).chain()
  .setColor("#edeae5").setOverlay("text:Press%20Start%202P_16:TROY%2520ORL").chain()
  .setColor("#000000").setEffect("shadow:5").setX(2).setY(2).chain()
  .setFlags("layer_apply").setGravity("north_west").setX(38).setY(50)).generate("bobson.jpg")!, cloudinary: cloudinary)
Board with two names

That’s a tedious task, involving a load of manual work to calculate the text positions. A much more efficient way would be to describe each position as a row and a column, and have Cloudinary do the math. Here’s what to do:

  1. Create a named transformation, bobson_name, with three arguments (col, row, and player) to store the calculation.

    Copy to clipboard
    co_rgb:edeae5,l_text:Press Start 2P_16:$(player)/co_rgb:000000,e_shadow:5,x_2,y_2/fl_layer_apply,g_north_west,x_$col_mul_294_sub_256,y_10_add_$row_mul_20

    A simple substitution takes care of the player name. For col, multiply it by the column width (294 pixels) and then subtract an offset of 256 pixels. For row, multiply it by the row height (20 pixels) and add a 10-pixel further offset.

    The result is a replacement of the two transformations above with the following:

    Copy to clipboard
    $player_!GBANT%20NOLAV!,$col_1,$row_1/t_bobson_name/$player_!TROY%20ORL!,$col_1,$row_2/t_bobson_name/

    Note
    First specify the variables and then invoke the transformation, once per text overlay. Strings are surrounded by instances of !; integers have no special surrounding characters.

  2. Now effortlessly add the remaining players:

Copy to clipboard
$player_!GBANT%20NOLAV!,$col_1,$row_1/t_bobson_name/$player_!TROY%20ORL!,$col_1,$row_2/t_bobson_name/$player_!SCOTT%20JIRVEY!,$col_1,$row_3/t_bobson_name/$player_!TIM%20OBSHIRE!,$col_1,$row_4/t_bobson_name/$player_!JIMMIE%20QEITZON!,$col_1,$row_5/t_bobson_name/$player_!TATH%20PELLICH!,$col_1,$row_6/t_bobson_name/$player_!RANDALL%20KIIKN!,$col_1,$row_7/t_bobson_name/$player_!RAYLOND%20WOKJ!,$col_1,$row_8/t_bobson_name/$player_!PHILIP%20FERQY!,$col_1,$row_9/t_bobson_name/$player_!SIDNEY%20KUVALAS!,$col_1,$row_10/t_bobson_name/$player_!WILBUR%20WISUZK!,$col_1,$row_11/t_bobson_name/$player_!ROMAN%20SHIOLDS!,$col_2,$row_1/t_bobson_name/$player_!GEORGE%20DICKINSUN!,$col_2,$row_2/t_bobson_name/$player_!LOUIS%20STHAEFER!,$col_2,$row_3/t_bobson_name/$player_!DOYLE%20CIRKERY!,$col_2,$row_4/t_bobson_name/$player_!FELIPE%20ZAST!,$col_2,$row_5/t_bobson_name/$player_!BRUCE%20WOYLE!,$col_2,$row_6/t_bobson_name/$player_!CONRAD%20FEHE!,$col_2,$row_7/t_bobson_name/$player_!DARRYL%20KOORE!,$col_2,$row_8/t_bobson_name/$player_!MIGUEL%20SHAMPLIN!,$col_2,$row_9/t_bobson_name/$player_!TIM%20MKANT!,$col_2,$row_10/t_bobson_name/$player_!DANNY%20TANFORD!,$col_2,$row_11/t_bobson_name

The image then looks like this:

Ruby:
Copy to clipboard
cl_image_tag("bobson.jpg", :variables=>[["$player", "!DANNY TANFORD!"], ["$col", "2"], ["$row", "11"]], :transformation=>[
  {:quality=>"auto"},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]},
  {:transformation=>["bobson_name"]}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("bobson.jpg", array("variables"=>array("$player"=>"!DANNY TANFORD!", "$col"=>"2", "$row"=>"11"), "transformation"=>array(
  array("quality"=>"auto"),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name")),
  array("transformation"=>array("bobson_name"))
  )))
PHP v2:
Copy to clipboard
(new ImageTag('bobson.jpg'))
  ->delivery(Delivery::format(Format::auto()))
  ->delivery(Delivery::quality(Quality::auto()))
  ->addVariable(Variable::set('player', 'GBANT NOLAV'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 1))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'TROY ORL'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 2))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'SCOTT JIRVEY'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 3))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'TIM OBSHIRE'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 4))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'JIMMIE QEITZON'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 5))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'TATH PELLICH'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 6))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'RANDALL KIIKN'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 7))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'RAYLOND WOKJ'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 8))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'PHILIP FERQY'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 9))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'SIDNEY KUVALAS'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 10))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'WILBUR WISUZK'))
  ->addVariable(Variable::set('col', 1))
  ->addVariable(Variable::set('row', 11))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'ROMAN SHIOLDS'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 1))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'GEORGE DICKINSUN'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 2))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'LOUIS STHAEFER'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 3))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'DOYLE CIRKERY'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 4))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'FELIPE ZAST'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 5))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'BRUCE WOYLE'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 6))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'CONRAD FEHE'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 7))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'DARRYL KOORE'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 8))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'MIGUEL SHAMPLIN'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 9))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'TIM MKANT'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 10))
  ->namedTransformation(NamedTransformation::name('bobson_name'))
  ->addVariable(Variable::set('player', 'DANNY TANFORD'))
  ->addVariable(Variable::set('col', 2))
  ->addVariable(Variable::set('row', 11))
  ->namedTransformation(NamedTransformation::name('bobson_name'));
Python:
Copy to clipboard
CloudinaryImage("bobson.jpg").image(variables={"$player": "!DANNY TANFORD!", "$col": "2", "$row": "11"}, transformation=[
  {'quality': "auto"},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]},
  {'transformation': ["bobson_name"]}
  ])
Node.js:
Copy to clipboard
cloudinary.image("bobson.jpg", {variables: [["$player", "!DANNY TANFORD!"], ["$col", "2"], ["$row", "11"]], transformation: [
  {quality: "auto"},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
.variables(variable("$player","!DANNY TANFORD!"),variable("$col","2"),variable("$row","11")).chain()
  .quality("auto").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name")).imageTag("bobson.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('bobson.jpg', {variables: [["$player", "!DANNY TANFORD!"], ["$col", "2"], ["$row", "11"]], transformation: [
  {quality: "auto"},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bobson.jpg", {variables: [["$player", "!DANNY TANFORD!"], ["$col", "2"], ["$row", "11"]], transformation: [
  {quality: "auto"},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]},
  {transformation: ["bobson_name"]}
  ]})
React:
Copy to clipboard
<Image publicId="bobson.jpg" variables={[["$player", "!DANNY TANFORD!"], ["$col", "2"], ["$row", "11"]]}>
  <Transformation quality="auto" />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
  <Transformation transformation={["bobson_name"]} />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="bobson.jpg" :variables="[['$player', '!DANNY TANFORD!'], ['$col', '2'], ['$row', '11']]">
  <cld-transformation quality="auto" />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
  <cld-transformation transformation={["bobson_name"]} />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="bobson.jpg" variables="[['$player', '!DANNY TANFORD!'], ['$col', '2'], ['$row', '11']]">
  <cl-transformation quality="auto">
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
  <cl-transformation transformation={{["bobson_name"]}}>
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Quality("auto").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name").Chain()
  .Named("bobson_name")).BuildImageTag("bobson.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
.variables(variable("$player","!DANNY TANFORD!"),variable("$col","2"),variable("$row","11")).chain()
  .quality("auto").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name").chain()
  .named("bobson_name")).generate("bobson.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setQuality("auto").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name").chain()
  .setNamed("bobson_name")).generate("bobson.jpg")!, cloudinary: cloudinary)
Final image

Our very own Fighting Baseball team is now for real, complete with Scott Jirvey, Louis Sthaefer, and Bruce Woyle. See the live image, which was generated from seed 66219.

To add context, cite a random team name, assisted by faker.js and the pluralize library:

Copy to clipboard
function headerText() {
  return `Meet Your Amazing ${1950 + rand(71)} ${faker.address.city()} ${pluralize(faker.commerce.productName())}!`;
}

Feel free to build your own teams and rosters by clicking Redraft the team! and inspect the source code. Have a blast.

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