Подтвердить что ты не робот

Обратный отсчет времени изображения GIF в электронной почте

Недавно я получил почтового ящика из Onnit Labs, который включал таймер обратного отсчета в почтовом устройстве, используя изображение gif. По электронной почте можно посмотреть здесь: https://www.onnit.com/emails/lastchance-historic/

Изображение можно увидеть здесь:

enter image description here

Я просмотрел его, и кажется, что вы можете продолжать отправлять новые кадры в анимированный GIF с помощью gifsockets, поскольку GIF не определяет, сколько фреймов оно имеет при загрузке в браузере. Здесь он находится на github: http://github.com/videlalvaro/gifsockets

Я думал, что это было довольно интересно и действительно здорово. Есть ли у кого-нибудь другое представление о том, как это можно сделать? Кажется, что тот, который они используют в Onnit, по-видимому, меняет обратный отсчет в соответствии с датой, добавленной в конце URL-адреса или изображения.

onnit.com/emails/_modules/timer/?end=2012-12-27+00:00:00&dark=1

Я пытаюсь выполнить одно и то же, чтобы отправить по электронной почте, но я немного озадачен.

4b9b3361

Ответ 1

Хотя возможно gifsockets будет работать (я не пробовал это раньше...), нет сетевого трафика, пока я смотрю на изображение, отличное от начальной загрузки изображения. Я также вижу, что он прыгает с 41 до 42 снова. Перезагрузка уменьшилась до 39.

Кажется, это всего лишь script, который генерирует 60 кадров анимации и отправляет их пользователю. Вероятно, это можно сделать на любом языке.

Вот как это делается в php:

http://seanja.com/secret/countdown/

enter image description here

Ответ 2

Я нашел http://sendtric.com/, который является бесплатным и очень легко интегрируется.

Ответ 3

Я очень ценю ответ шона Джа. (Он заслуживает большего количества голосов.) И затем я хотел сделать код более читабельным и настраиваемым (и поддерживать текст на прозрачном GIF и автоматически центрировать текст):

use Carbon\Carbon;
class CountdownGifHelper {

    const DELAY = 100; /* Why was this labeled as 'milliseconds' when it seems like a value of 100 here causes 1 frame to be shown per second? */
    const MAX_FRAMES = 120;

    /**
     * 
     * @param string $bgImg
     * @param \DateInterval $interval
     * @param array $fontArr
     * @param array $frames
     * @param array $delays
     * @param string $format
     */
    public function addFrame($bgImg, $interval, $fontArr, &$frames, &$delays, $format) {
        $image = imagecreatefrompng($bgImg); //Each frame needs to start by creating a new image because otherwise the new numbers would draw on top of old ones. Here, it does not really matter what the PNG is (other than for size) because it about to get filled with a new color.
        $text = $interval->format($format);
        ob_start();
        imageSaveAlpha($image, true);
        $backgroundColor = $fontArr['backgroundColor'];
        imagefill($image, 0, 0, $backgroundColor); //https://stackoverflow.com/a/17016252/470749 was a helpful hint
        imagecolortransparent($image, $backgroundColor);
        $this->insertCenteredText($image, $fontArr, $text);
        //imagettftext($image, $font['size'], $font['angle'], $font['x-offset'], $font['y-offset'], $font['color'], $font['file'], $text);//this was the old way
        imagegif($image); //The image format will be GIF87a unless the image has been made transparent with imagecolortransparent(), in which case the image format will be GIF89a.
        $frames[] = ob_get_contents();
        ob_end_clean();
        $delays[] = self::DELAY;
    }

    /**
     * 
     * @param resource $image
     * @param array $fontArray
     * @param string $text
     */
    public function insertCenteredText(&$image, $fontArray, $text) {
        $image_width = imagesx($image);
        $image_height = imagesy($image);
        $text_box = imagettfbbox($fontArray['size'], $fontArray['angle'], $fontArray['file'], $text); // Get Bounding Box Size
        $text_width = $text_box[2] - $text_box[0];
        $text_height = $text_box[7] - $text_box[1];
        // Calculate coordinates of the text https://stackoverflow.com/a/14517450/470749
        $x = ($image_width / 2) - ($text_width / 2);
        $y = ($image_height / 2) - ($text_height / 2);
        imagettftext($image, $fontArray['size'], $fontArray['angle'], $x, $y, $fontArray['color'], $fontArray['file'], $text);
    }

    /**
     * 
     * @param int $timestamp
     * @param string $bgImg
     * @param array $fontArray
     * @return string [can be used by Laravel response()->make($gifString, 200, $headers)]
     */
    public function getAnimatedGif($timestamp, $bgImg, $fontArray) {
        $future_date = Carbon::createFromTimestamp($timestamp);
        $time_now = time();
        $moment = new \DateTime(date('r', $time_now));
        $frames = [];
        $delays = [];
        for ($i = 0; $i <= self::MAX_FRAMES; $i++) {
            $interval = date_diff($future_date, $moment);
            if ($future_date < $moment) {
                $this->addFrame($bgImg, $interval, $fontArray, $frames, $delays, '00 : 00 : 00');
                $loops = 1; //stay stuck on this frame
                break;
            } else {
                $this->addFrame($bgImg, $interval, $fontArray, $frames, $delays, '%H : %I : %S');
                $loops = 0; //infinite loop
            }
            $moment->modify('+1 second');
        }
        $animatedGif = new \App\Helpers\AnimatedGif($frames, $delays, $loops, 0, 0, 0);
        return $animatedGif->getAnimation();
    }

    /**
     * ONEDAY allow config via params
     * @param resource $image
     * @return array
     */
    public function getFontArray($image) {
        $fontArr = [
            'file' => resource_path('assets/fonts/Kanit-Regular.ttf'),
            'size' => 30,
            //'x-offset' => 5,
            //'y-offset' => 30,
            'color' => imagecolorallocate($image, 90, 90, 90), //gray
            'backgroundColor' => imagecolorallocate($image, 0, 0, 0), //white. Must match the arguments provided to AnimatedGif (such as 0,0,0).
            'angle' => 0,
        ];
        return $fontArr;
    }

}

Ответ 4

Вы можете попробовать http://makedreamprofits.com/pt/. Вместо того, чтобы предоставлять дополнительный контент для GIF, этот обратный отсчет разбит на отдельные изображения и может рассчитывать до 20 минут без увеличения трафика.

Постскриптум Gmail проповедует изображения, поэтому бесконечно снабжать его новыми кадрами невозможно.