响应微博小秘书倡议 连夜加急撸出头像变灰小工具之开发历程
- 2020 年 4 月 4 日
- 筆記
昨天看到了微博小秘书关于全国性悼念活动倡议,我非常支持这个倡议。 因为修改灰色头像会有一定技术门槛,于是思考能否开发一个小工具方便大家使用。 考虑到第二天就是哀悼日,准备夜间快速开发上线。
0X00 废话少说先上东西
有兴趣的老哥可以访问:http://smartding.top:81/ 或者 http://smartding.top:8080/
因为暂时无法备案,所以只能采用带端口或者纯 IP 的方式访问,有点郁闷。
小工具里面记录了项目历程,有兴趣可以阅读,
0X01 选型
因为时间相当有限,技术选型必须选择较为成熟的脚手架型框架。
基于这样的原则出发,前端框选用 Element.io,Element.io 优势是支持 CDN 引用,你甚至不需要创建一个 Webpack 项目,提供的组件既有颜值也非常稳定可靠,文档也十分齐全。后端框架则采用 Springboot,通过简单引入 Springboot 依赖就可以轻松创建一个 Java web 项目。
0X02 核心算法
技术选型完成之后,开始考虑核心算法也就是如何把彩色图片转为灰度图片。我没有图片处理经验,但经过摸索大致了解了转换方法。转换算法其实就是下面的数学公式:
gray(red, green, blue) = (red + green + blue)/3
主要思路是把求得每个像素的RGB 三色平均值,如此把三维的颜色空间映射到一维的灰度空间。通过逐一转换图片的每一个像素,最终我们得到一副只包含灰度的图片。
具体实现如下:
int width = img.getWidth(); int height = img.getHeight(); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int p = img.getRGB(j, i); int a = (p >> 24) & 0xff; int r = (p >> 16) & 0xff; int g = (p >> 8) & 0xff; int b = p & 0xff; int avg = (r + g + b)/3; //replace RGB value with avg p = (a << 24) | (avg << 16) | (avg << 8) | avg; img.setRGB(j, i, p); } }
0X03 对抗恶意刷流
第二个难点是如何既保证使用体验又避免恶意刷流量,考虑到应用的生命周期极短,我采用的方法是带宽采用按流量计费,应用中增加单 IP 下载次数限制, Guava 的 Cache 类很好的满足了我需求。
具体实现如下:
// Cache 定义,注意到 expireAfterWrite 非常关键,它用来控制限流周期。 private final LoadingCache<String, AtomicInteger> cache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.DAYS).build(new CacheLoader<String, AtomicInteger>() { @Override public AtomicInteger load(final String s) throws Exception { return new AtomicInteger(0); } }); // 超限检查 String ip = request.getRemoteAddr(); AtomicInteger counter = cache.get(ip); if (counter.getAndIncrement() > 50) { log.error("ip {} try too many time, rejected!", ip); throw new RuntimeException("try too many!"); }
0X04 总结
这是我的一个人作品,甚至我还获得的人生的第一粒金(有慷慨老哥支持了 0.1 元),这个项目技术难度不高,最难的部分其实是推广,即如何让更多的人了解到你的作品,这个是我的短板。不管怎么说,我离正式创业项目也迈进了一步,尽管没有什么收入能做出一个有价值的小工具我也非常高兴。
觉得好有可以分享给朋友,感谢啦。