gadl/browser.go
2023-12-13 23:20:31 +09:00

134 lines
2.7 KiB
Go

package main
import (
"encoding/base64"
"errors"
"net/http"
"net/url"
"strings"
"github.com/playwright-community/playwright-go"
)
type RawImageFile struct {
URL string
Blocks []map[string]int
Width *int
Height *int
}
type File struct {
ContentType string
Data []byte
}
var draw = `
async function drawImage(imageFile) {
const canvas = Object.assign(document.createElement("canvas"), {
width: imageFile.width,
height: imageFile.height,
});
const image = (await new Promise((resolve) => {
Object.assign(new Image(), {
crossOrigin: "use-credentials",
src: imageFile.url,
onload() {
resolve(this);
},
});
}));
const ctx = canvas.getContext("2d");
for (const q of imageFile.blocks) {
ctx.drawImage(image, q.destX, q.destY, q.width, q.height, q.srcX, q.srcY, q.width, q.height);
}
const dataUrl = canvas.toDataURL();
return dataUrl;
}
`
var fetch = `
async function fetchImage(imageFile) {
const res = await fetch(imageFile.url);
const blob = await res.blob();
const dataUrl = await new Promise((resolve, reject) => {
const fileReader = Object.assign(new FileReader(), {
onload() {
resolve(this.result);
},
onerror(e) {
const error = new Error(` + "`${e.type}: ${e.message}`" + `);
reject(error);
},
});
fileReader.readAsDataURL(blob);
});
return dataUrl;
}
`
func parseDataURL(dataURL string) (*File, error) {
if !strings.HasPrefix(dataURL, "data:") {
return nil, errors.New("not data scheme")
}
parts := strings.SplitN(dataURL, ",", 2)
if len(parts) != 2 {
return nil, errors.New("invalid data URL")
}
raw, err := url.PathUnescape(parts[1])
if err != nil {
return nil, err
}
var data []byte
if strings.HasSuffix(parts[0], ";base64") {
data, err = base64.StdEncoding.DecodeString(raw)
if err != nil {
return nil, err
}
} else {
data = []byte(raw)
}
file := File{
ContentType: http.DetectContentType(data),
Data: data,
}
return &file, nil
}
type BrowserContext interface {
*playwright.BrowserContext
}
// TODO
// export type Browser = {
// loadBrowserContext(platform: TPlatform): Promise<Playwright.BrowserContext>;
// saveBrowserContext(platform: TPlatform, ctx: BrowserContext): Promise<void>;
// newContext(): Promise<Playwright.BrowserContext>;
// close(): Promise<void>;
// drawImage(
// pageOrFrame: Playwright.Page | Playwright.Frame,
// imageFile: ImageFile,
// ): Promise<Blob>;
// };
type Browser struct {
}
func (b *Browser) New() (*Browser, error) {
pw, err := playwright.Run()
if err != nil {
return nil, err
}
browser, err := pw.Chromium.Launch()
if err != nil {
return nil, err
}
b.Pw = pw
b.Browser = browser
return b, nil
}