不过多废话,展示完整步骤
GO
package main
import (
"bytes"
"fmt"
"image"
"image/draw"
"image/jpeg"
"log"
"syscall/js"
)
func CropImage(this js.Value, inputs []js.Value) interface{} {
imageData := inputs[0]
x := inputs[1].Int()
y := inputs[2].Int()
w := inputs[3].Int()
h := inputs[4].Int()
// 将 JavaScript Uint8Array 转换为 Go 字节切片
dataBytes := make([]byte, imageData.Length())
js.CopyBytesToGo(dataBytes, imageData)
// 裁剪图像
croppedImage, err := cropHandle(dataBytes, x, y, w, h)
if err != nil {
log.Println("Error cropping image:", err)
return nil
}
// 创建一个新的 Uint8Array,并将裁剪后的图像数据复制进去
croppedArray := js.Global().Get("Uint8Array").New(len(croppedImage))
js.CopyBytesToJS(croppedArray, croppedImage)
return croppedArray
}
func cropHandle(dataBytes []byte, X, Y, W, H int) ([]byte, error) {
// 使用 image 包解码图像数据
img, _, err := image.Decode(bytes.NewReader(dataBytes))
if err != nil {
return nil, fmt.Errorf("error decoding image: %w", err)
}
// 创建一个 WxH 大小的图像
croppedImg := image.NewRGBA(image.Rect(0, 0, W, H))
//从X,Y位置开始裁剪图像
draw.Draw(croppedImg, croppedImg.Bounds(), img, image.Point{X, Y}, draw.Src)
// 编码裁剪后的图像为 JPEG 格式
var buf bytes.Buffer
err = jpeg.Encode(&buf, croppedImg, nil)
if err != nil {
return nil, fmt.Errorf("error encoding image: %w", err)
}
return buf.Bytes(), nil
}
func main() {
c := make(chan struct{}, 0)
js.Global().Set("CropImage", js.FuncOf(CropImage))
<-c
}
这里给了一个示例,导出了一个裁剪图像的函数,接收Uint8Array类型数据和裁剪起始坐标以及裁剪宽高
使用下面的命令打包wasm文件,cmd窗口执行,注意golang需要版本>11
set GOOS=js
set GOARCH=wasm
go build -o main.wasm main.go
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<script src="wasm_exec.js"></script>
<title>GO_wasm测试</title>
</head>
<body>
<img style="width: 300px;" src="http://annew.320.io:8880/api/uploads/file/1f6439b8442141db143a319722917241_20240124113134.jpg" alt="">
<p>使用wasm裁剪上面的图像</p>
<hr>
</body>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("./main.wasm"), go.importObject)
.then((result) => {
go.run(result.instance);
fetch("http://annew.320.io:8880/api/uploads/file/1f6439b8442141db143a319722917241_20240124113134.jpg")
.then(response => response.blob())
.then(blob => {
return blob.arrayBuffer();
})
.then(arrayBuffer => {
// 创建 Uint8Array
const uint8Array = new Uint8Array(arrayBuffer);
const CropImageValue = CropImage(uint8Array,340,860,2320,2370);
// console.log(CropImageValue);
const img = document.createElement('img');
img.src = URL.createObjectURL(new Blob([CropImageValue], { type: 'image/jpeg' }));
img.width = 300;
document.body.appendChild(img);
});
}).catch((err) => {
console.error(err);
});
function CropImage(uint8Array,X,Y,W,H) {
return window.wasmCropImage(uint8Array,X,Y,W,H);
}
</script>
</html>
wasm_exec.js 从golang的安装目录获取:C:\Program Files\Go\misc\wasm
js示例,获取图片的文件流,转为uint8Array,并传递给golang导出的函数获得处理后的uint8Array数据,再将其渲染到页面。