0

I'm using Imagemagick to dynamic generating an OpenGraph Image.
I'm processing that image step by step, means:

  1. Resize the image to 1200px width
  2. Grayscale the image
  3. Make image transparent
  4. Multiply the transparent image with the filter color

After creating the background image I'm starting to add the elements.

  1. Adding the Mainline
  2. -> 8. Adding some other elements

Unfortunately after generating that image there are some strange fragments around the text and the images I overlaid.

Any Idea how to avoid this?

I attached some images to demonstrate the problem.

Fragments around text Fragments aroung images

EDIT:
I hope this helps

Link to SRC Image

$imagename = uniqid() . ".jpg";
$image = $og_upload_path . '/' . $imagename;

$alpha = 15
$filterColor = "#08e2dd"; // Light Blue

// Asset images for processing the opengraph image
$white_background = $image_path . "/white.png";

$src_image = [Link to src image see above];

// Resize Image to 1200px width
    system("convert '" . $src_image . "' -resize 1200 '" . $image . "'");

    // Grayscale Image
    system("convert '" . $image . "' -colorspace Gray '" . $image . "'");

    // Make image transparent
    system("composite -blend " . $alpha . " '" . $image . "' '" . $white_background . "' '" . $image . "'");

    // Multiply Image with filter color
    system("convert '" . $image . "' \ "
      . " \( -clone 0 -fill '" . $filterColor . "' -colorize 100 \) \ "
      . " -compose multiply \ "
      . " -composite '" . $image . "'"
    );

    // Add MainLine Text
    system("convert '" . $image . "' -size 1000x -background transparent \ "
      . " -fill '" . $textColor_MainLine . "' \ "
      . " -pointsize " . $fontSize_MainLine . " \ "
      . " -font " . $path_fontfile . " \ "
      . " -gravity center caption:" . $text_MainLine . " \ "
      . " -gravity center -composite '" . $image . "'"
    );
Yves
  • 1,152
  • 1
  • 23
  • 30

3 Answers3

2

JPG is a lossy image format, and ImageMagick's convert utility doesn't retain the highest quality by default:

For the JPEG and MPEG image formats, quality is 1 (lowest image quality and highest compression) to 100 (best quality but least effective compression). The default is to use the estimated quality of your input image if it can be determined, otherwise 92. When the quality is greater than 90, then the chroma channels are not downsampled. Use the -sampling-factor option to specify the factors for chroma downsampling.

You can set -quality 100 in your commands, but you'd be best off manipulating your image in lossless image formats, and then converting to a lossy format (like JPG) for smaller file size.

Jacob Budin
  • 9,753
  • 4
  • 32
  • 35
  • It works ... almost - Now I get a nice picture without any fragments even with zoom level 400 but if I upload that image to facebook it still has that fragments around the text as you can see in this [Comparison Image](http://cl.ly/ZBf5). But maybe that's another question? – Yves Jan 06 '15 at 16:52
  • 1
    @yves Facebook compresses all media uploaded to its platform. They want their users' browsing to be fast and snappy, even if it sacrifices quality, so they can serve more ads. There's nothing you can do about their manipulation post-upload. – Jacob Budin Jan 06 '15 at 16:54
  • But I don't really understand why these fragments are just in my images, I tried it with several others (few text, many text, smaller, larger, different backgrounds ...) but it doesn't happen at any of these. – Yves Jan 06 '15 at 17:13
  • @yves Can you provide examples? All user-generated content on Facebook—even the ads themselves—have compression artifacts. – Jacob Budin Jan 06 '15 at 17:16
  • Ok, you're right there are some fragments as well. But it doesn't look so nasty like this [example](http://cl.ly/ZC0F). – Yves Jan 06 '15 at 18:07
  • Here I have a [sample](http://cl.ly/ZC6H) of the generated image with just 3 Lines of Text. After generating it looks nice and crispy but after I post that image to fb, it get's really nasty. – Yves Jan 06 '15 at 18:19
1

Stay in PNG format as long as possible and only go to JPG at the very last stage. Also. compound your calls to convert into as few as possible to avoid de-compressing and re-compressing. Thus you can do your first 4 calls to convert in one step like this:

convert https://s3.amazonaws.com/f.cl.ly/items/0E0V2M29313B3b0p1x2W/og_image.png \
   -resize 1200                                                                  \
   -colorspace gray                                                              \
   -evaluate multiply 0.15 -evaluate add 55700                                   \
   \( +clone -fill "#08e2dd" -colorize 100 \) -compose multiply -composite       \
   output.png

I recast your composite command to blend 85% white as multiplying by 0.15 and adding 85% of 65,535 (i.e. 55700) which is white in a 16-bit quantisation. That saves you having to keep a white.png file lying around for no good reason (since we know all pixels will be 65535 anyway) and allows us to do everything with convert instead of having to save and use composite and save and revert to convert.

I'll let you check the quality and processing time and add in the last step yourself.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 1
    I have improved this answer and simplified your processing quite a lot. Please have another look. – Mark Setchell Jan 06 '15 at 21:06
  • Thanks @mark-setchell even if it doesn't change the quality after posting it's cleaner and especially nicer because of the white image replacement. – Yves Jan 07 '15 at 09:36
0

Thanks all for your great and fast replies.

At the end the compression of Facebook is really the problem. If you upload it by hand it gets blurry and really nasty but if you just use it as an OpenGraph image it's great. The Answers and comments were helping me a lot!

Yves
  • 1,152
  • 1
  • 23
  • 30