当前位置: 首页 > Web前端 > HTML

扔掉Electron后,我用Tauri+Rust+Wasm开发了一个图片压缩应用

时间:2023-03-28 13:19:40 HTML

鍓嶈█浣滀负涓€涓墠绔紑鍙戣€咃紝浣犳槸涓嶆槸宸茬粡鍘屽€︿簡姣忔UI缁欑殑鍒囧浘澶у埌鎯宠窇甯︾潃姘存《绂诲紑锛熻繕涓嶆墦绠楁彁妗跺氨鍋滀笅鏉ワ紝鐪嬪畬杩欑瘒鏂囩珷鍐嶈窇涔熶笉杩焴鍏堥湶鑴稿惂锛屾垜鍙獻mageTiny銆傜矖鐣ョ湅涓嬪帇缂╃巼锛宲ng銆乯pg鏍煎紡鍩烘湰鍙互杈惧埌80%宸﹀彸锛実if鍙互杈惧埌11%宸﹀彸銆傚績鍔ㄤ簡鍚楌煉擄紝杩樹笉閿欏惂锛熷姛鑳戒粙缁嶆敮鎸佺殑鍥剧墖鏍煎紡鏈塸ng銆乯pg銆乬if鏀寔5M浠ヤ笂鍥剧墖鍘嬬缉涓嶄緷璧栫綉缁滐紝涓嶄緷璧栨湇鍔″櫒锛屽熀浜庡鎴风鏈湴鍘嬬缉鏀寔鎷栨嫿鍥剧墖鏂囦欢杩涜鍘嬬缉鏀寔鍘嬬缉璐ㄩ噺鍙傛暟璋冩暣鏀寔缃《绐楀彛鏀寔鍗曞紶鍥剧墖淇濆瓨鏀寔涓€閿墦鍖咃紝灏嗗垪琛ㄤ腑鎵€鏈夊浘鐗囦繚瀛樹负zip鍖呬繚瀛樺埌鏈湴鍘嬬缉鐜囧姣擳inyPNGTinyPNG杩欎釜鍦ㄧ嚎鍥剧墖鍘嬬缉缃戠珯锛屽墠绔紑鍙戣€呮兂蹇呴兘涓嶉檶鐢熴€傛敮鎸乸ng銆乯pg銆亀ebp鏍煎紡鐨勫浘鐗囧帇缂╋紝鍘嬬缉鐜囬潪甯搁珮銆備篃寰堜笉閿欙紝鑲畾鏈夊緢澶氭湅鍙嬬敤杩囥€傛墍浠mageTiny閫夋嫨鍜孴inyPNG瀵规瘮銆備笅闈㈡槸4寮爌ng銆?寮爅pg銆?寮爂if鍥剧墖鐨勫帇缂╂暟鎹姣旓細瀵逛簬png鏍煎紡鐨勫浘鐗囷紝ImageTiny鐨勫帇缂╃巼鍩烘湰鍙互杈惧埌TinyPNG鐨勬按骞筹紱瀵逛簬jpg鏍煎紡鐨勫浘鐗囷紝缁忚繃娴嬭瘯锛孖mageTiny鐨勫帇缂╄川閲忚皟鏁村埌80%浠ヤ笅锛屽彲浠ヨ秴瓒奣inyPNG锛涘浜巊if鏍煎紡鐨勫浘鐗囷紝鎶辨瓑锛孴inyPNG涓嶆敮鎸侊紱瀵逛簬5MB鍙婁互涓婄殑鍥剧墖锛屾姳姝夛紝TinyPNG涓嶆敮鎸侊紱鎬荤殑鏉ヨ锛屾垜浠殑ImageTiny杩樻槸寰堜笉閿欑殑锛岃€屼笖鏄畬鍏ㄥ厤璐圭殑锛屼笉渚濊禆缃戠粶锛屼笉渚濊禆鏈嶅姟鍣ㄣ€傚帇缂╂妧鏈疄鐜版牳蹇冧娇鐢╨ibimagequant銆乴ibpng銆乴ibjpeg銆乬ifsicle瀹炵幇鍥剧墖鍘嬬缉锛屼娇鐢‥mscriptenSDK锛坋msdk锛夊皢C浠g爜缂栬瘧鎴恮asm鏂囦欢渚涙祻瑙堝櫒璋冪敤銆傚叿浣撶殑鍘嬬缉浠g爜杩欓噷灏变笉灞曠ず浜嗐€傝繖涓」鐩湁寮€婧愯鍒掞紝鍒版椂鍊欏ぇ瀹跺彲浠ョ湅鍒般€傚簲鐢ㄦ鏋禩auri+Rust+Vue3.0+Vite瀵筎auri涓嶇啛鎮夌殑鍙互鐪嬩箣鍓嶅彂琛ㄧ殑涓€绡囨枃绔狅細鎺橀噾閾炬帴馃敆锛氭墧鎺塃lectron锛屾嫢鎶盩auri寰俊鍏紬鍙烽摼鎺ヰ煍楀熀浜嶳ust寮€鍙戯細鎵旀帀Electron鍜屾嫢鎶卞熀浜嶳ust鐨凾auri浠g爜peepif(datas.winTop==='windowontop'){curWin.setAlwaysOnTop(true);datas.winTop='鍙栨秷缃《';}else{curWin.setAlwaysOnTop(false);datas.winTop='椤堕儴绐楀彛';}}浠嶡tauri-apps/api寮曞叆windowapi锛岄€氳繃window.getCurrent鏂规硶鑾峰彇褰撳墠window瀹炰緥銆傚疄渚嬩笂鏈塻etAlwaysOnTop鏂规硶锛屽彲浠ラ€氳繃鍙傛暟true\false鎺у埗绐楀彛缃《鎴栧彇娑堢疆椤躲€傝嚦浜庝负浠€涔堣鍦ㄥ簲鐢ㄤ腑鍔犲叆windowtop馃敐鍔熻兘锛岃繖閲屽厛鎸栦竴涓潙锛屼互鍚庡啀濉€?.娣诲姞main.rsusetauri::{Menu,MenuItem,Submenu};fnmain(){letsubmenu_main=Submenu::new("ImageTiny".to_string(),Menu::new()letmenu=Menu::new().add_submenu(submenu_main);tauri::Builder::default().menu(menu).run(tauri::generate_context!()).expect("errorwhilerunningtauriapplication");}寮曞叆鑿滃崟锛孧enuItem,Submenu锛岄€氳繃Submenu::new()鏂规硶鏂板缓涓€涓彍鍗曢」锛岃皟鐢╝dd_native_item鏂规硶鍦ㄩ噷闈㈡坊鍔犲師鐢熺殑MenuItem椤癸紝鐒跺悗鏂板缓涓€涓狹enu锛岄€氳繃Menu::new灏哠ubmenu娣诲姞鍒伴噷闈?).add_submenu()鏂规硶鍦ㄨ彍鍗曚腑锛屾渶鍚庨€氳繃tauri::Builder::default().menu()灏嗚彍鍗曟敞鍐屽埌搴旂敤涓€?.鎷栨斁鍥剧墖鍘嬬缉鍔熻兘...

functiondragenterEvent(event){event.stopPropagation();event.preventDefault();}functiondragoverEvent(event){event.stopPropagation();event.preventDefault();}functiondragleaveEvent(event){event.stopPropagation();event.preventDefault();}functiondropEvent(event){event.stopPropagation();浜嬩欢.preventDefault();constfiles=event.dataTransfer.files;displayChsFile(files);}鍒╃敤娴忚鍣ㄧ殑鎷栨嫿浜嬩欢鐩戝惉鎷栨嫿Drag锛屽湪drop浜嬩欢涓幏鍙栨枃浠朵俊鎭€俤rop浜嬩欢杩斿洖鐨勫弬鏁版槸涓€涓狣ragEvent瀵硅薄銆傛瀵硅薄涓婃湁涓€涓猟ataTransfer瀛楁銆傝繖涓瓧娈典笅闈㈡湁涓€涓猣iles瀛楁锛岀敤鏉ュ瓨鏀炬垜浠渶瑕佺殑FileList锛屼篃灏辨槸鎴戜滑鎷栨嫿鐨凢ileObject銆傛嬁鍒癋ileList鍚庯紝浼犻€掔粰displayChsFile鏂规硶鏉ラ亶鍘嗗帇缂╁浘鐗囨枃浠躲€俆ips锛氶渶瑕佺鐢╰auri鎻愪緵鐨勬枃浠舵嫋鎷戒簨浠讹紝浠g爜濡備笅tauri.conf.json{..."tauri":{"windows":[{..."fileDropEnabled":false,...}],}...}4.鍥剧墖鏂囦欢鍘嬬缉鍔熻兘涓轰簡鏂逛究鍏徃鍏朵粬椤圭洰鎺ュ叆鍥剧墖鍘嬬缉鍔熻兘锛屾垜浠皢姝ゆ牳蹇冧唬鐮佸皝瑁呬簡涓€涓鏈夌殑npm鎻掍欢锛屾柟渚垮悇涓」鐩殑鎺ュ叆銆傛垜浠湅涓€涓嬩唬鐮侊細importpngtinyfrom'../plugins/pngtiny'/***@description:鍥剧墖鍘嬬缉*@param{File}fileoriginalFile鏂囦欢瀵硅薄*@param{Number}quality鍘嬬缉璐ㄩ噺锛?0-90,80鎺ㄨ崘*@return{Promise}鍘嬬缉鏂囦欢瀵硅薄*/constimageTiny=(file,quality=80)=>{pngtiny.run()returnnewPromise((resolve,reject)=>{try{constreader=newFileReader()reader.readAsArrayBuffer(file)reader.onload=function(e){constfcont=newUint8Array(e.target.result)constfsize=fcont.byteLengthconstdataptr=pngtiny._malloc(fsize)constretdata=pngtiny._malloc(4)pngtiny.HEAPU8.set(fcont,dataptr)pngtiny._tiny(dataptr,fsize,retdata,璐ㄩ噺)璁﹔data=newInt32Array(pngtiny.HEAPU8.buffer,retdata,1)constsize=rdata[0]rdata=newUint8Array(pngtiny.HEAPU8.buffer,dataptr,size)constblob=newBlob([rdata],{type:file.type})璁﹐utFile=newFile([blob],file.name,{type:file.type})if(outFile.size===0){outFile=file}resolve(outFile)pngtiny._free(dataptr)pngtiny._free(retdata)}}catch(error){reject(error)}})}exportdefaultimageTiny閫氳繃emsdk灏咰浠g爜缂栬瘧鎴怶ebAssembly鏃讹紝浼氱敓鎴?wasm鏂囦欢鍜?js鑳舵按浠g爜锛岃繖娈礿s鑳舵按浠g爜浼氬鐞唚asm鏂囦欢锛屾垜浠彧闇€瑕佷娇鐢ㄥ鍑虹殑pngtiny瀵硅薄锛岄噷闈㈠寘鍚簡鎴戜滑闇€瑕佷娇鐢ㄧ殑鏂规硶imageTiny鏂规硶鐨勮緭鍏ュ弬鏁颁负锛歠ile:File鏂囦欢瀵硅薄quality:compressedqualityoutput:compressedFile鏂囦欢瀵硅薄5.淇濆瓨鍗曞紶鍥剧墖鍑芥暟import{writeBinaryFile}from'@tauri-apps/api/fs';import{path,dialog}from'@tauri-apps/api';//淇濆瓨鍗曚釜鍥惧儚asyncfunctionhandleSaveFile(file){datas.tip='Imageisbeingsaved...';constbasePath=awaitpath.downloadDir();璁﹕elPath=awaitdialog.save({defaultPath:basePath,});selPath=selPath.replace(/Untitled$/,'');constreader=newFileReader();reader.readAsArrayBuffer(file.data);reader.onload=function(e){letfileU8A=newUint8Array(e.target.result);writeBinaryFile({鍐呭锛歠ileU8A锛岃矾寰勶細`${selPath}${file.data.name}`});datas.tip='淇濆瓨鍥剧墖鎴愬姛';};}寮曞叆tauri鐨刟pi锛歸riteBinaryFile,path,dialog锛屼娇鐢╠ialog.save()鏂规硶鎵撳紑鏂囦欢淇濆瓨瀵硅瘽妗嗕緵鐢ㄦ埛閫夋嫨淇濆瓨璺緞锛岃鏂规硶鏈変竴涓猟efaultPath鍙傛暟璁剧疆榛樿淇濆瓨璺緞锛岃鏂规硶鐨勮繑鍥炲€兼槸鏈€缁堣淇濆瓨鐨勬枃浠惰矾寰勩€傛垜浠€夋嫨绯荤粺榛樿鐨勪笅杞借矾寰勪綔涓洪粯璁ょ殑淇濆瓨璺緞锛岀郴缁熼粯璁ょ殑涓嬭浇璺緞鍙互閫氳繃path.downloadDir()鏂规硶鑾峰彇銆傞渶瑕佺壒鍒敞鎰忕殑鏄紝鐢变簬鏂囦欢淇濆瓨瀵硅瘽妗嗛粯璁ゆ彁渚涚殑鏂囦欢鍚嶆槸Untitled锛屽鏋滃紑鍙戣€呬笉淇敼鎴栧垹闄わ紝dialog.save()鏂规硶杩斿洖鐨勮矾寰勪腑浼氬寘鍚竴绾ntitled鐩綍锛屾垜浠彲浠ユ墜鍔ㄦ嫤鎴€俬andleSaveFile鏂规硶鎺ユ敹鍒扮殑鍙傛暟鏄竴涓狥ile瀵硅薄锛岄噷闈㈠寘鍚簡褰撳墠鍥剧墖鏂囦欢鐨勫熀鏈俊鎭互鍙婃垜浠嚜瀹氫箟鐨勪竴浜涗俊鎭紝濡備笅鍥炬墍绀猴細閫氳繃FileReaderapi璇诲彇鍥剧墖鏂囦欢鐨刄int8Array鏁版嵁锛屽苟浣跨敤tauri鎻愪緵鐨剋riteBinaryFileapi銆傚湪鏈湴鍐欏叆鏂囦欢銆倃riteBinaryFile鎺ュ彈涓€涓璞″弬鏁帮紝鍖呮嫭contents鍜宲ath瀛楁锛宑ontents鏄枃浠剁殑Uint8Array鏁版嵁锛宲ath鏄淇濆瓨鐨勮矾寰勩€備负浜嗘柟渚跨敤鎴凤紝鎴戜滑灏嗘枃浠跺悕鎷兼帴鍦ㄨ矾寰勪笂锛岃繖鏍风敤鎴峰氨涓嶉渶瑕佸湪淇濆瓨鏂囦欢瀵硅瘽妗嗕腑鎵嬪姩濉啓鏂囦欢鍚嶏紝鐩存帴淇濆瓨鍗冲彲銆?.涓€閿繚瀛樺姛鑳絠mportJSZipfrom'jszip';//涓€閿繚瀛榓syncfunctionhandleDownloadAll(){constlen=datas.imgList.length;濡傛灉(len===0){杩斿洖;}datas.tip='zip淇濆瓨涓?..';constzip=newJSZip();for(leti=0;i{letfile=newFileReader();file.readAsArrayBuffer(content);file.onload=function(e){letfileU8A=newUint8Array(e.target.result);writeBinaryFile({鍐呭锛歠ileU8A锛岃矾寰勶細`${selPath}IMG_${鍛ㄤ竴+鏃?灏忔椂+鍒嗛挓}.zip`});datas.tip='鍘嬬缉鍖呬繚瀛樻垚鍔?;};});}鎴戜滑浣跨敤jszip鎻掍欢鏉ュ帇缂╂枃浠堕鍏堟垜浠娇鐢╪ewJSZip()鍒涘缓涓€涓獄ip瀹炰緥锛岄亶鍘嗗帇缂╂枃浠跺垪琛紝璋冪敤zip.file()鏂规硶娣诲姞鏂囦欢銆俧ile()鏂规硶鎺ユ敹涓や釜鍙傛暟锛屼竴涓槸鏂囦欢鍚嶏紝涓€涓槸鏂囦欢鐨勫唴瀹规暟鎹€傜劧鍚庝娇鐢╠ialog.save()api璋冪敤鏂囦欢淇濆瓨寮瑰嚭妗嗭紝鑾峰彇淇濆瓨璺緞锛岃皟鐢▃ip.generateAsync鏂规硶鐢熸垚zip鍖呯殑ArrayBuffer鏁版嵁锛岄€氳繃writeBinaryFile灏嗘枃浠跺啓鍏ユ湰鍦版帴鍙c€俆ips锛氬帇缂╁寘鐨勫懡鍚嶆柟寮忛€夋嫨鑾峰彇骞存湀鏃ヤ俊鎭潵鍛藉悕銆傝俯杩囩殑鍧?.Tauri鐗堟湰閫夋嫨杩欎釜鍙互璇存槸鏈€澶х殑鍧戜簡銆備负浠€涔堣繖涔堣鍛紝鎴戜滑缁х画寰€涓嬬湅銆傚湪椤圭洰寤鸿涔嬪垵锛屾垜婊℃€€鏈熷緟鐨勯€夋嫨浜嗘渶鏂扮増鏈殑tauri锛屼絾鏄綋鍔熻兘寮€鍙戝埌鏂囦欢绯荤粺鐩稿叧鐨凙PI鏃讹紝鍗粹€嬧€嬮亣鍒颁簡涓€涓弗閲嶇殑闂锛歎nhandledPromiseRejection:cannottraversedirectory銆俆auri鐨刦s鐩稿叧API鏃犳硶璇诲彇浠讳綍璺緞涓嬬殑鏂囦欢銆備粈涔堬紵杩欐€庝箞鑳藉ソ鐜╁憿锛熶箣鍓嶈繕鏄彲浠ョ敤鐨勶紝闅鹃亾鏄増鏈棶棰橈紵鎴戝甫鐫€闂鍜宼auri绀惧尯杩涜浜嗕氦娴併€傛渶缁堢瓟妗堟槸锛氬嚭浜庡畨鍏ㄨ€冭檻锛屽湪鏂扮増鏈腑锛宖s鐩稿叧鐨凙PI鏈夊畨鍏ㄩ檺鍒讹紝鍙兘璁块棶tauri鎻愪緵鐨勫嚑涓郴缁熻矾寰勪笅鐨勬枃浠躲€傝繖鏍疯偗瀹氫笉琛岋紝鎴戜滑涓嶈兘璁╃敤鎴峰帇缂╀竴寮犲浘鐗囷紝闈炲緱鎶婂浘鐗囨斁鍦ㄦ寚瀹氱殑鐩綍涓嬫墠鑳借闂€備簬鏄粬浠妸杩欎釜闂鍙嶉缁欎簡tauri绀惧尯锛屼粬浠〃绀哄悗缁増鏈細璁″垝灏嗙敤鎴烽€夋嫨鐨勮矾寰勫姞鍏ョ櫧鍚嶅崟鏉ョ粫杩囪繖涓檺鍒躲€傚緱鍒扮瓟妗堝悗锛岃В鍐虫柟妗堟槸鍥炴粴tauri鐗堟湰锛屾墍浠ュ彧鑳藉洖婊氬埌鏃х増鏈€傚叿浣撶増鏈俊鎭涓嬶細package.json"@tauri-apps/api":"=1.0.0-beta.8","@tauri-apps/cli":"=1.0.0-beta.10",Cargo.toml[build-dependencies]tauri-build={version="=1.0.0-beta.4"}[dependencies]serde={version="1.0",features=["derive"]}serde_json="1.0"tauri={version="=1.0.0-beta.8",features=["api-all"]}濡傛灉鏈夊叾浠栧皬浼欎即鍦ㄤ娇鐢╰auri鐨勬椂鍊欙紝鎴戜篃閬囧埌浜嗘枃浠惰闂檺鍒剁殑闂銆傛偍鍙互鍙傝€冧笂闈㈢殑鐗堟湰銆?銆侀€夋嫨鏂囦欢涓婁紶鏂瑰紡涓€鑸湁3绉嶆柟寮忥紝鎴戜滑涓€涓€鏉ョ湅銆?.杈撳叆涓婁紶鏂瑰紡琚玹auri绂佹锛屾枃浠堕€夋嫨瀵硅瘽妗嗘牴鏈墦涓嶅紑銆?銆乼auri鎻愪緵鐨勫叏灞€鎷栨嫿浜嬩欢import{listen}from'@tauri-apps/api/event';listen('tauri://file-drop',async(event)=>{console.log(event);});閫氳繃鐩戝惉tauri鎻愪緵鐨則auri://file-drop浜嬩欢锛屽彲浠ュ緱鍒颁簨浠剁殑浜嬩欢瀵硅薄锛屼細杩斿洖鏂囦欢璺緞銆傛病閿欙紝杩斿洖鐨勫彧鏄枃浠惰矾寰勫垪琛紝鎴戜滑杩橀渶瑕侀亶鍘嗘枃浠惰矾寰勫垪琛紝浣跨敤fs鐩稿叧鐨刟pi璇诲彇姣忔潯璺緞瀵瑰簲鐨勬枃浠躲€傝繖涓繃绋嬫极闀夸笖鑰楁椂锛屼綋楠屾瀬宸€?.Drap&drop浜嬩欢閫氳繃鐩戝惉drop浜嬩欢锛屽彲浠ョ洿鎺ヨ幏鍙栦笂浼犵殑FileList瀵硅薄锛岄噷闈㈠寘鍚簡鏂囦欢鐨勫叿浣撲俊鎭紝鏂逛究蹇嵎锛屾墍浠ユ湰鏂囦篃閲囩敤浜嗚繖绉嶆柟妗堛€傚~鍧戯細涓轰粈涔堣娣诲姞绐楀彛缃《鍔熻兘锛熷洜涓篒mageTiny鐨勫浘鐗囦笂浼犳柟寮忔槸鎷栨嫿涓婁紶锛屽鏋滄病鏈夌獥鍙g疆椤跺姛鑳斤紝寰堝鏄撹鍏朵粬搴旂敤鎸′綇锛屼細澶уぇ闄嶄綆鐢ㄦ埛浣撻獙銆傛湁浜嗙疆椤跺姛鑳斤紝鐢ㄦ埛鏃犻渶鎷呭績閬尅銆傚畨瑁呭寘璐$尞馃敆浠g爜浠撳簱馃敆瀹夎鍖呭湴鍧€娆㈣繋澶у涓嬭浇瀹夎浣跨敤銆傚鏋滄湁鐢紝鍒繕浜嗙粰鏂囩珷鐐逛釜璧烉煈嶐煆伙紝濡傛灉鑳借浆鍙戣鏇村鐨勬湅鍙嬬湅鍒扳€嬧€嬪氨鏇村ソ浜嗐€傜患涓婃墍杩帮紝鎴戣姳浜嗗皢杩戜竴鍛ㄧ殑鏃堕棿鎵嶅畬鎴愪簡鏁翠釜搴旂敤鐨勫紑鍙戙€傝繖鏈熼棿锛岃俯杩囩殑鍧戞暟涓嶈儨鏁帮紝鎴戜篃鍦ㄤ笉鏂湴鑻﹁嫤瀵绘壘瑙e喅闂鐨勫姙娉曘€備笉杩囧紑鍙戝畬鎴愬悗锛屽績閲岃繕鏄緢楂樺叴鐨勶紝甯屾湜鑳界敤Tauri寮€鍙戞洿澶氱殑灏忓伐鍏凤紝缁欏ぇ瀹跺甫鏉ヤ竴鐐规柟渚縹鏇村绮惧僵锛岃鍏虫敞鎴戜滑鐨勫叕浼楀彿鈥滅櫨鐡剁鎶€鈥濓紝濡傛灉鎮ㄦ湁浠讳綍鐤戦棶瀹氭湡绂忓埄锛?/p>