響應微博小秘書倡議 連夜加急擼出頭像變灰小工具之開發歷程
- 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 元),這個項目技術難度不高,最難的部分其實是推廣,即如何讓更多的人了解到你的作品,這個是我的短板。不管怎麼說,我離正式創業項目也邁進了一步,儘管沒有什麼收入能做出一個有價值的小工具我也非常高興。
覺得好有可以分享給朋友,感謝啦。