Using ImageMagick to manipulate GIF graphs

Time:2021-9-12

In the last article, we have learned many functions in graphicsmagick. We also said that graphicsmagick is a branch of ImageMagick, so many of their functions are used in the same way and effect. We won’t say more about similar contents. Interested friends can directly consult the official documents.

In this article, we want to learn a specific case, which is also a case I have come into contact with in actual business development. The specific effect is that for wechat games and applets, dynamic GIF images cannot be used directly. A GIF image will not move in a game or applet. Therefore, in the game development of our company, we need to assemble a picture of each frame of the whole GIF motion picture into a sprite picture and give it to the front end. They can dynamically cycle the pictures after we split the frame using the ability of JS + CSS, so as to form the effect of motion picture.

This is the case for business requirements. Of course, the final solution is implemented using ImageMagick. Without much to say, let’s look at the code first.

Gif image framing

The original picture is a moving picture:

https://imgs.developpaper.com/imgs/1575433-20210823084945947-496567660.gif

$imgPath = '../img/4.gif';
$imagick = new \Imagick($imgPath);
$imagick = $imagick->coalesceImages();
$imageCount = $imagick->count();
echo 'image count:', $imageCount, PHP_EOL; // image count:51

$imgAttrs = [
    'width'       => $imagick->getImageWidth(),
    'height'      => $imagick->getImageHeight(),
    'frame_count' => $imageCount,
];
$column = 5;
if ($imageCount < $column) {
    $column = $imageCount;
}

$row = ceil($imageCount / $column);

$spImgWidth = $imgAttrs['width'] * $column;
$spImgHeight = $imgAttrs['height'] * $row;

 //Create picture
$spImg = new \Imagick();
$spImg->setSize($spImgWidth, $spImgHeight);
$spImg->newImage($spImgWidth, $spImgHeight, new \ImagickPixel('#ffffff00'));
$spImg->setImageFormat('png');

$i = 0;
$h = 0;
$cursor = 0;
do {
    if ($i == $column) {
        $i = 0;
        $h++;
    }
    If ($cursor = = 0) {// save the first picture
        $imagick->writeImage($imgPath . '.first.png');
    }
    //Save all picture frames to a PNG picture
    $spImg->compositeImage($imagick, \Imagick::COMPOSITE_DEFAULT, $i * $imgAttrs['width'], $h * $imgAttrs['height']);
    $i++;
    $cursor++;
} while ($imagick->nextImage());
$spImg->writeImage($imgPath . '.png');

Needless to say, when instantiating the imageick object, we first call the coalesceimages () method. Its function is to return the synthesized imageick object. Through this method, we can get the information of each frame in the whole GIF image. At this time, using the count () method, you can obtain the number of all picture frames in the picture. For example, the picture we tested has 51 frames.

Then calculate the rows and columns of the sprite graph and the corresponding required width and height. For example, we take 5 columns as the benchmark, that is, put five disassembled pictures in one row. In this way, a total of 11 rows are needed to put the last generated sprite graph. Similarly, the width and height is the width and height of the disassembled image multiplied by the corresponding number of columns and rows.

Then, a new image is generated according to the calculated width and height as the background image of the sprite image. Use the newimage() function to set the width and height of the image and the transparency of the background. Use the setimageformat () method to set the format of the picture to PNG format. PNG is mainly used for transparency. In fact, according to our closely arranged pictures, it is OK not to be transparent, but in some applications, such as the sprite map required by the front end of the website, a certain interval may be required before different pictures, so transparent basemap is generally used.

Then there is a cycle, that is, to cycle the 51 split frame pictures, use nextimage() to continuously obtain the next frame picture in the original GIF picture, and save them in the new background picture above. The picture position of each frame is also calculated by the width, height and row and column of a single frame picture. In this code, we also save the picture of the first frame. Of course, this is also a business need. You can save any picture of each frame at any time.

Finally, use writeimage () to save the image. The output image looks like this:

https://img2020.cnblogs.com/other/1575433/202108/1575433-20210823084945947-496567660.gif.png

Combine into dynamic GIF diagram

The above business functions are the functions I have actually used in development. Of course, in addition to the framing of GIF diagram, we can also combine multiple pictures into a dynamic GIF diagram.

$gifImagek = new Imagick();
$gifImagek->setFormat('GIF');

for($i=1;$i<=5;$i++){
    $img = new Imagick('../img/3'.$i.'.jpeg');
    $img->setImageDelay(100);
    $gifImagek->addImage($img);
}

$gifImagek->writeImages("../img/5.gif", true);
$gifImagek->writeImages("../img/52.gif", false);

This code is relatively simple. Still create an image and specify the format as GIF image. Then add the pictures in a loop. Here we use the pictures operated in graphicsmagick in the previous article. Setimagedelay() is used to set the picture display interval. Here, we set 100 milliseconds, and then use addimage() to add the picture to our newly created GIF picture cloth.

Finally, when saving pictures, you need to use writeimages() to save them. Its function is to save such continuous multiple pictures. Its second parameter is to specify whether to save the picture to a picture. If false, it is similar to the effect of frame splitting, but the pictures will be saved separately, such as 52-1.gif and 52-2.gif.

The final generated dynamic graph is as follows:

https://imgs.developpaper.com/imgs/1575433-20210823084947098-1859907648.gif

summary

Today’s content is interesting. It’s not the scaling, watermarking, verification code and other functions of those rotten streets, but the fun operation of GIF graph. To be honest, there are still many similar business scenarios in business development. For example, the function of automatically generating wizard diagram can be realized by ImageMagick, and all of them can be solved by the built-in functions in ImageMagick extension, which is very convenient.

Test code:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/5. Using ImageMagick to manipulate gif graph.php

Reference documents:

https://www.php.net/manual/zh/book.imagick.php

Official account: hard core project manager

Add wechat / QQ friends: [xiaoyuezigonggong / 149844827] get free PHP and project management learning materials

Tiktok, official account, voice, headline search, hard core project manager.

Station B ID: 482780532

Recommended Today

Beautify your code VB (VBS) code formatting implementation code

However, vb.net does have many new functions that VB6 does not have. The automatic typesetting of code is one, which is the function we want to realize today – VB code formatting.Let’s look at the effect: Before formatting: Copy codeThe code is as follows: For i = 0 To WebBrowser1.Document.All.length – 1 If WebBrowser1.Document.All(i).tagName = […]