美文网首页
为啥微信添加个动态表情这么难?

为啥微信添加个动态表情这么难?

作者: adousj | 来源:发表于2016-09-12 01:23 被阅读35次

每每看到好玩 gif 想要跟基友分享,结果发过去就成了死图。搜了半天才知道,要添加到微信表情才可以,照着添加了,结果又提示 “所选图片太大”!!!
What the f**?我只是单纯的想分享一张 gif 动图,咋还生出这么多幺蛾子。

拿 Graphics-Magic 练练手,程序中会多次尝试缩放直到结果 1M以下。

#include <cassert>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>

#include <boost/format.hpp>
#include <gflags/gflags.h>
#include <Magick++.h> 

DEFINE_int32(max_size, 1024, "output file size in Kb");
DEFINE_string(in, "", "input image filename");
DEFINE_string(out, "", "output image filename");
DEFINE_int32(retry, 3, "max retry times");
//DEFINE_int32(depth, 8, "output image depth");
//DEFINE_int32(quality, 75, "output image quality");

int read_image_vec(const std::string& filename, std::vector<Magick::Image>& image_vec) {
    assert(image_vec.empty());
    try {
        Magick::readImages(&image_vec, filename);
    } catch (Magick::Warning &warning) {
        std::cerr << warning.what() << std::endl;
    } catch (Magick::Error &error) {
        std::cerr << error.what() << std::endl;
    }

    return !image_vec.empty() && image_vec.front().isValid() ? 0 : 1;
}

Magick::Geometry image_vec_page(const std::vector<Magick::Image>& image_vec) {
    assert(!image_vec.empty());
    Magick::Geometry max_page(0, 0);
    for (const auto& image : image_vec) {
        auto page = image.page();
        if (page.width() > max_page.width()) {
            max_page.width(page.width());
        }
        if (page.height() > max_page.height()) {
            max_page.height(page.height());
        }
    }
    return max_page;
}

Magick::Geometry image_vec_size(const std::vector<Magick::Image>& image_vec) {
    assert(!image_vec.empty());
    Magick::Geometry max_size(0, 0);
    for (const auto& image : image_vec) {
        auto size = image.size();
        if (size.width() > max_size.width()) {
            max_size.width(size.width());
        }
        if (size.height() > max_size.height()) {
            max_size.height(size.height());
        }
    }
    return max_size;
}

double guess_resize_ratio(const off_t src_file_size,
                          const off_t max_file_size) {
    static double FILE_SIZE_RATIO = 1.0;
    FILE_SIZE_RATIO = std::max(0.5, FILE_SIZE_RATIO - 0.1);
    return sqrt(max_file_size * FILE_SIZE_RATIO / src_file_size);
}

void image_vec_resize(std::vector<Magick::Image>& image_vec, const double ratio) {
    assert(!image_vec.empty());
    assert(ratio > 0);

    for (auto& image : image_vec) {
        auto page = image.page();

        auto size = image.size();
        size.width(size.width() * ratio);
        size.height(size.height() * ratio);
        image.thumbnail(size);

        page.width(page.width() * ratio);
        page.height(page.height() * ratio);
        page.xOff(page.xOff() * ratio);
        page.yOff(page.yOff() * ratio);
        image.page(page);
    }
}

size_t image_vec_encode(std::vector<Magick::Image>& image_vec, Magick::Blob& blob) {
    assert(!image_vec.empty());

    /*
    for (auto& image : image_vec) {
        if (image.depth() > FLAGS_depth) {
            image.depth(FLAGS_depth);
        }

        if (image.quality() > FLAGS_quality) {
            image.quality(FLAGS_quality);
        }

        //image.type(Magick::OptimizeType);
    }
    */

    writeImages(image_vec.begin(), image_vec.end(), &blob);
    return blob.length();
}

int main(int argc, char** argv) {
    google::SetVersionString("1.0.0.0");
    google::ParseCommandLineFlags(&argc, &argv, true);

    Magick::InitializeMagick("./");

    std::vector<Magick::Image> image_vec;
    if (0 != read_image_vec(FLAGS_in, image_vec)) {
        std::cerr << "read input error" << std::endl;
        return -1;
    }

    std::cout << boost::format("frame: %1%") % image_vec.size() << std::endl;

    auto src_page = image_vec_page(image_vec);
    if (!src_page.isValid()) {
        std::cerr << boost::format("invalid page: %1%x%2%") % src_page.width() % src_page.height()
                  << std::endl;
        return -1;
    }
    std::cout << boost::format("page: %1%x%2%") % src_page.width() % src_page.height()
              << std::endl;

    auto src_file_size = image_vec.front().fileSize();
    std::cout << boost::format("fileSize: %1%") % src_file_size << std::endl;

    off_t max_file_size = FLAGS_max_size * 1024;
    if (src_file_size <= max_file_size) {
        std::cout << "max_size no more than source file size, no need to resize" << std::endl;
        return 0;
    }

    // strip
    for_each(image_vec.begin(), image_vec.end(), Magick::stripImage());

    for (auto i = 0; i < FLAGS_retry; ++i) {
        std::cout << boost::format("try the %1% time") % (i + 1) << std::endl;
        std::cout << boost::format("    src page: %1%x%2%  fileSize: %3%")
                                   % src_page.width() % src_page.height()
                                   % src_file_size
                  << std::endl;
        auto ratio = guess_resize_ratio(src_file_size, max_file_size);
        image_vec_resize(image_vec, ratio);
        Magick::Blob blob;
        auto dst_file_size = image_vec_encode(image_vec, blob);
        auto dst_page = image_vec_page(image_vec);
        std::cout << boost::format("    dst page: %1%x%2%  fileSize: %3%")
                                   % dst_page.width() % dst_page.height()
                                   % dst_file_size
                  << std::endl;
        if (dst_file_size <= max_file_size) {
            std::ofstream ofs(FLAGS_out, std::ostream::out);
            ofs.write(static_cast<const char*>(blob.data()), blob.length());
            return 0;
        } else {
            src_file_size = dst_file_size;
            src_page = dst_page;
        }
    }

    std::cerr << "convert faild" << std::endl;
    return -1;
}

相关文章

  • 为啥微信添加个动态表情这么难?

    每每看到好玩 gif 想要跟基友分享,结果发过去就成了死图。搜了半天才知道,要添加到微信表情才可以,照着添加了,结...

  • 公众号emoji/微信表情回复详解

    微信及QQ表情 QQ表情及微信表情是什么? QQ表情虽然呈现为一张张动态的表情图片,但在微信公众平台的消息接口中却...

  • 民咕咕微信动态表情

    民咕咕微信动态表情图,大放送

  • 我的微信没有了好友

    朋友,加个微信。 同学,加个微信。 ...... 当我创建了自己的微信后,微信里的好友在持续膨胀。 微信的信息提示...

  • 加个微信

    家里打算要购置一张双人床,打算购买皮质的大床。 午饭后先生在手机上挑床,说是无意中看抖音的博主拍出来好看,接着加了...

  • 少看点朋友圈

    “妹纸,加个微信吧。。。” "您可以关注我们的微信公众号,我们会第一时间更新动态的。。。" “麻烦等一下蛤,我先发...

  • 蛙妈妈的蛙儿子回去了吗

    最近非常火爆的一款游戏突然就被刷屏了,打开微信,看着朋友圈里各式各样关于青蛙的动态: “为啥我的青蛙这么淘,都不着...

  • 加个好友,就这么难!

    打开QQ,一看,哇哦,自己居然收到了十六条邀请,其中四条邀请入群,还有十二条是加友申请。 群就不入了吧,不是疯狂折...

  • 木木来啦~~

    柏思科技吉祥物木木表情包上线啦,耶~ 动态表情传送门: 静态表情传送门: 微信公众号:Workfine数据管理平台...

  • “加个微信吧”

    1. 很久不刷微博了,心血来潮把前天在海边拍的比基尼秀身材美照po上去,并装逼的配文“休个年假胖了7斤的宝宝/哭脸...

网友评论

      本文标题:为啥微信添加个动态表情这么难?

      本文链接:https://www.haomeiwen.com/subject/yucpettx.html