思思久久精品无码|久久一区二区精品综合|天堂亚洲aⅤ在线观看|国产日韩一区二区2022|搡老女人老91妇女老熟女|成人无码精品免费视频在线|在线人成精品视频在线观看免费|久久人人爽人人爽人人片av高

?? 詳解一鍵生成邀請(qǐng)海報(bào)工具 | Rust 與 WebAssembly

保健品 nanfang 2023-12-25 06:21 144 0

背景:用 Rust 與 WebAssembly 為 Rust China Conf 做了一個(gè)快速生成海報(bào)的工具,在線體驗(yàn)記得點(diǎn)擊閱讀原文,查看文章文中的資源插播一條消息 ?? 用 Serverless 部署 TensorFlow AI 推理函數(shù),就可以獲得 Rust 搪瓷杯、Serverless 口罩與貼紙的活動(dòng)正在進(jìn)行中,。

歡迎大家前來(lái)參加以下為正文,Enjoy!??在辦各種技術(shù)大會(huì)的時(shí)候,主辦方都會(huì)給參與者制作帶有個(gè)人名字的邀請(qǐng)海報(bào),以顯示對(duì)參會(huì)者的重視,同時(shí)也希望達(dá)到最大范圍的傳播邀請(qǐng)海報(bào)一般的工作流:設(shè)計(jì)確定好海報(bào)樣式;。

運(yùn)營(yíng)提供給設(shè)計(jì)名字;設(shè)計(jì)根據(jù)名字一張一張輸出海報(bào);運(yùn)營(yíng)再把海報(bào)一上游企業(yè)張一張發(fā)給參與者;如果我們只有兩位數(shù)的參與者,那使用這個(gè)工作流工作是沒(méi)有問(wèn)題的但是當(dāng)我們面向的是 300 人規(guī)模的 Rust China Conf 的時(shí)候,這個(gè)工作流的工作量就過(guò)于大了些,需要更多人力支持。

再加上雖然 Rust 社區(qū)中的開(kāi)發(fā)者無(wú)法到現(xiàn)場(chǎng)參與大會(huì),依然也想轉(zhuǎn)發(fā) Rust 大會(huì)海報(bào),為 Rust China Conf 打 Call在這種情況下,統(tǒng)計(jì)人名,再讓設(shè)計(jì)志愿者一張一張輸出海報(bào),并把海報(bào)發(fā)給指定的人,對(duì)只有個(gè)位數(shù)的 Rust China Conf 組委會(huì)來(lái)說(shuō),基本上是不可能完整完成的任務(wù)。

不就是改改參數(shù)嗎???那要怎么辦呢?既然是辦 Rust China Conf,首先想到的上游企業(yè)還是要用 Rust 解決當(dāng)然,Rust 與 WebAssembly 的集合很適合圖片處理這種計(jì)算密集型函數(shù)我們這家創(chuàng)業(yè)公司(Second  State)在成立的時(shí)候,就堅(jiān)定地認(rèn)為用 Rust 與 Wasm 做 serverless 是云計(jì)算的未來(lái)。

所以很自然地就想到我們之前用 Rust 函數(shù)寫(xiě)的的 watermark demo為什么不把水印變成名字/昵稱(chēng),這樣就可以讓開(kāi)發(fā)者自己在網(wǎng)頁(yè)上輸入名字,然后就能生成一張專(zhuān)屬邀請(qǐng)海報(bào)使用 Serverless 的好處是只需為所使用的資源付費(fèi),成本也能 Cover 住。

使用 Second State Functions 給出的例子,需要解決的是找到一個(gè)中英上游企業(yè)文通用的字體,沒(méi)有任何版權(quán)問(wèn)題重新計(jì)算 watermark 在海報(bào)上的位置,居中放置watermark 的顏色與大小

#[wasm_bindgen]pub fn watermark (img_buf: &[u8]) -> Vec {    // 讀取輸入的圖片let mut img = image::load_from_memory(img_buf).unwrap();

let (w,h) = img.dimensions();let scale = Scale {      x: w as f32 /10.0,      y: h as f32 /10.0,    };

// 準(zhǔn)備 waterma上游企業(yè)rk 的字體let font = Vec::from(include_bytes!("DejaVuSans.ttf") as &[u8]);let font = Font::try_from_vec(font).unwrap();

    // 在輸入的圖片畫(huà)出 watermark    drawing::draw_text_mut(&mut img, image::Rgba([255u8, 255u8, 255u8, 255u8]), 0+(h/10),h/2, scale, &font, 

"Hello Second State");    // 編寫(xiě)并返回已經(jīng)加好水印的照片let mut buf = 上游企業(yè)vec![];    img.write_to(&mut buf, image::ImageOutputFormat::Png).unwrap();

return buf;}let font = Vec::from(include_bytes!("DejaVuSans.ttf") as &[u8]);  在這里替換字體,用 PingFang Bold.ttf

 替換原來(lái)的字體PingFang Bold.ttf 支持中英文,也與 Rust China Conf 的主 kv 字體一致,是個(gè)完美的選擇Rgba([255u8, 255u8, 255u8, 255u8]), 0+(h/10),h/2,。

在這里上游企業(yè)調(diào)整顏色的 RGB 值與位置,RGB 值也就是水印的顏色根據(jù)海報(bào)的背景最終選定白色再接下來(lái)就是通過(guò)調(diào)整 0+(h/10),h/2, 調(diào)整字體的位置了經(jīng)過(guò)幾次調(diào)試后,終于找到了基本上是居中的位置雖然還有一點(diǎn)小瑕疵,但是看起來(lái)還不錯(cuò),可以用了。

效果如下圖:

original.png改參數(shù)也是要技巧的 ??但是很快又有一個(gè)問(wèn)題出現(xiàn),中英文長(zhǎng)度不一樣如果輸入的名字是 Second State Functions,英文字符過(guò)長(zhǎng),而且文字不是居中的,甚至超出了圖片的安全區(qū)域。

?? ?? ??簡(jiǎn)單地調(diào)整位置參數(shù)的做法并不能很好解決這個(gè)問(wèn)題尤其現(xiàn)在是多元化環(huán)境,大家的昵稱(chēng)五花八門(mén),無(wú)法判斷輸入文字的大小、也無(wú)法上游企業(yè)判斷是否輸入的是中文,還是中英混雜我們需要再多寫(xiě)點(diǎn) Rust,來(lái)確保輸入的文字,無(wú)論長(zhǎng)短,無(wú)論中英文,都能夠居中顯示,這樣才能達(dá)到為任何人生成定制海報(bào)的目的。

之前提到的代碼已經(jīng)告訴了我們?nèi)绾卧趫D片上添加文字,并輸出新的圖片那我們?cè)僦牢淖之?huà)到圖片上的尺寸,就能實(shí)現(xiàn)文字的居中顯示啦那么如何獲取到這個(gè)尺寸呢?我們的解決思路是,輸入文字后,函數(shù)會(huì)先按照基準(zhǔn)字號(hào)把文字畫(huà)到一張純白的圖片上,然后根據(jù)文字在這張圖片的表現(xiàn)自動(dòng)調(diào)整文字大小,從而保證文字一直居中并且大小合適。

const MAX_WIDTH : u32 = 349;const MAX_HEIGHT : u32 = 80;const MAX_FO上游企業(yè)NT_SIZE : f32 = 125.0;const FAR_LEFT : u32 = 200;

const FAR_TOP : u32 = 590;在 lib.rs  先確定了輸入文字的寬度與高度、基準(zhǔn)字號(hào)、文字的左上角位置,這里可以理解成先規(guī)定了一個(gè)安全區(qū)域當(dāng)我們輸入文字 Second State Functions。

之后,lib.rs 里的 watermark 函數(shù)的write_to_crop 函數(shù)先把文字按基準(zhǔn)字號(hào),即上文已經(jīng)確定好的 MAX_FONT_SIZE ,畫(huà)到 crop.png 上crop.png 就是我們上文提到的純白的圖片。

pub fn watermark (waterm上游企業(yè)ark_text: &str) -> Vec {let width = write_to_crop(watermark_text);let mut left = FAR_LEFT;

let mut top = FAR_TOP;let mut font_size = MAX_FONT_SIZE;接下來(lái), imagecrop.rs 里定義的結(jié)構(gòu)對(duì)象計(jì)算出白色背景上黑色文字所占據(jù)的寬度,這也就是水印畫(huà)到圖片上的基準(zhǔn)寬度。

使用基準(zhǔn)字號(hào),Second State Functions 的位置明顯過(guò)寬了,那就來(lái)調(diào)整字號(hào),lib.rs 里的 watermark 函數(shù)根據(jù) imagecrop 里計(jì)算出的基準(zhǔn)寬度,上游企業(yè)以及海報(bào)上允許放置文字的最大尺寸和相對(duì)位置,計(jì)算出能讓文字居中顯示的位置和字號(hào)。

if width < MAX_WIDTH {      left = FAR_LEFT + (MAX_WIDTH - width) / 2;    } else {      font_size = (MAX_WIDTH as f32) / (width as f32) * MAX_FONT_SIZE;

      top = FAR_TOP + ((1.0 - (MAX_WIDTH as f32) / (width as f32)) * (MAX_HEIGHT as f32)) as u32;    }

得出字號(hào)以及讓文字能夠居上游企業(yè)中顯示的位置后,剩下的工作就和前面提到的在圖片上添加文字完全一樣了當(dāng)完成了 Rust 程序以后,就可以編譯成 wasm 文件,并將其部署到 Second State Functions 上提供給外界使用。

這一步是通過(guò) ajax 的方式實(shí)現(xiàn)了這個(gè)服務(wù)這樣,任何拿到鏈接的人,都可以輸入自己的名字,生成一張定制的個(gè)人打 Call 海報(bào)

better.png生成適合自己的海報(bào),解放雙手 ??首先是 fork 這個(gè) github repo,然后就可以肆意更改了字體使用 ttf 格式我測(cè)試的時(shí)候,otf 格式的字體不能工作,如果有哪位大神知道原因,歡迎指出。

更改字體在 lib.rs 里template.pn上游企業(yè)g 是模板海報(bào),你可以替換成自己的海報(bào)如果你的海報(bào)寬度與我們的海報(bào)寬度一樣,且名字的位置也一樣,那么就不用調(diào)整任何參數(shù)了如果你的海報(bào)與我們的模板不一致,那你需要在 。

lib.rs  修改下面這些參數(shù)://文字安全區(qū)域的最大寬度const MAX_WIDTH : u32 = 349;//文字安全區(qū)域的最大高度const MAX_HEIGHT : u32 = 80;//最大允許字號(hào)

const MAX_FONT_SIZE : f32 = 125.0;//文字安全區(qū)域相對(duì)圖片左上角的偏移量const FAR_LEFT : u32 = 200;const FAR_TOP : u32 = 590;

改完參數(shù)上游企業(yè)之后,按照 github 上的 Readme 部署函數(shù),測(cè)試出最佳位置為了方便測(cè)試,我們?cè)?src 文件夾添加了 main.rs 文件最后使用 ajax 部署成一個(gè)網(wǎng)頁(yè),這樣就可以方便地把生成海報(bào)應(yīng)用分享給相關(guān)的人使用,解放雙手!。

 $.ajax({      url: "https://rpc.ssvm.secondstate.io:8081/api/run/149/watermark/bytes",type: "post",      data : $(

#input)[0].files[0],      contentType: "application/octet-stream",    上游企業(yè)  processData: false,      xhrFields:{

        responseType: blob      },      success: function (data) {        const img_url = URL.createObjectURL(data);

        $(#wm_img).prop(src, img_url);      }  });這或許也可以稱(chēng)為 Low Code RustHappy Coding!??Reference ??Mixing Text and Binary Data in Call Arguments

源碼執(zhí)行 Rust 函數(shù)的 WebA上游企業(yè)ssembly 虛擬機(jī) SSVM

標(biāo)簽列表