master
dustoair 2 years ago
commit 354f1fd62b

5
.gitignore vendored

@ -0,0 +1,5 @@
.idea
go.sum
*.png
*.jpg
*.webp

@ -0,0 +1,226 @@
package html2Img
import (
"context"
"errors"
"fmt"
"github.com/chromedp/cdproto/emulation"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
uuid "github.com/iris-contrib/go.uuid"
"os"
"time"
)
// FormatPng png jpg webp
const FormatPng = page.CaptureScreenshotFormatPng
// DefaultQuality jpg only
const DefaultQuality = 0
// DefaultFromSurface capture from surface rather than viewport
const DefaultFromSurface = true
// DefaultViewportX viewport x
const DefaultViewportX = 0
// DefaultViewportY viewport y
const DefaultViewportY = 0
const DefaultViewportWidth = 996
const DefaultViewportHeight = 996
const DefaultViewportScale = 1
// DefaultWaitingTime waiting time unit:Millisecond
const DefaultWaitingTime = 0
type Html2ImageParams struct {
page.CaptureScreenshotParams
CustomClip bool
WaitingTime int // Waiting time after the page loaded. Default 0 means not wait. unit:Millisecond
}
type CommonRequestDTO struct {
Url string `schema:"url,omitempty" validate:"required,url"`
UploadKey string `schema:"uploadKey,omitempty" validate:"omitempty"`
Username string `schema:"u,omitempty" validate:"required"`
Password string `schema:"p,omitempty" validate:"required"`
}
type Html2ImageRequestDTO struct {
CommonRequestDTO
Format page.CaptureScreenshotFormat `schema:"format,omitempty" validate:"omitempty"` // Image compression format (defaults to png).
Quality int64 `schema:"quality,omitempty" validate:"omitempty"` // Compression quality from range [0..100] (jpeg only).
CustomClip bool `schema:"customClip,omitempty" validate:"omitempty"` //if set this value, the below clip will work,otherwise not work!
ClipX float64 `schema:"clipX,omitempty" validate:"omitempty"` // Capture the screenshot of a given region only.X offset in device independent pixels (dip).
ClipY float64 `schema:"clipY,omitempty" validate:"omitempty"` // Capture the screenshot of a given region only.Y offset in device independent pixels (dip).
ClipWidth float64 `schema:"clipWidth,omitempty" validate:"omitempty"` // Capture the screenshot of a given region only.Rectangle width in device independent pixels (dip).
ClipHeight float64 `schema:"clipHeight,omitempty" validate:"omitempty"` // Capture the screenshot of a given region only.Rectangle height in device independent pixels (dip).
ClipScale float64 `schema:"clipScale,omitempty" validate:"omitempty"` // Capture the screenshot of a given region only.Page scale factor.
FromSurface bool `schema:"fromSurface,omitempty" validate:"omitempty"` // Capture the screenshot from the surface, rather than the view. Defaults to true.
WaitingTime int `schema:"waitingTime,omitempty" validate:"omitempty"` // Waiting time after the page loaded. Default 0 means not wait. unit:Millisecond
}
func NewDefaultHtml2ImageParams() Html2ImageParams {
return Html2ImageParams{
CustomClip: false,
CaptureScreenshotParams: page.CaptureScreenshotParams{
Format: FormatPng,
Quality: DefaultQuality,
Clip: &page.Viewport{
X: DefaultViewportX,
Y: DefaultViewportY,
Width: DefaultViewportWidth,
Height: DefaultViewportHeight,
Scale: DefaultViewportScale,
},
FromSurface: DefaultFromSurface,
},
WaitingTime: DefaultWaitingTime,
}
}
func newDefaultHtml2ImageRequestDTO() *Html2ImageRequestDTO {
return &Html2ImageRequestDTO{
Format: FormatPng,
Quality: DefaultQuality,
CustomClip: false,
ClipX: DefaultViewportX,
ClipY: DefaultViewportY,
ClipWidth: DefaultViewportWidth,
ClipHeight: DefaultViewportHeight,
ClipScale: DefaultViewportScale,
FromSurface: DefaultFromSurface,
WaitingTime: DefaultWaitingTime,
}
}
func convertToHtml2ImageParams(requestDTO *Html2ImageRequestDTO) Html2ImageParams {
params := NewDefaultHtml2ImageParams()
params.Format = requestDTO.Format
params.Quality = requestDTO.Quality
params.CustomClip = requestDTO.CustomClip
params.Clip.X = requestDTO.ClipX
params.Clip.Y = requestDTO.ClipY
params.Clip.Width = requestDTO.ClipWidth
params.Clip.Height = requestDTO.ClipHeight
params.Clip.Scale = requestDTO.ClipScale
params.FromSurface = requestDTO.FromSurface
params.WaitingTime = requestDTO.WaitingTime
return params
}
type ConvertConfig struct {
Url string `validate:"required,url"`
Params Params
}
type DoctronConfig struct {
TraceId uuid.UUID
Ctx context.Context
DoctronType int
ConvertConfig
}
type Params interface {
}
type Converter interface {
Convert() ([]byte, error)
GetConvertElapsed() time.Duration
}
type Conver struct {
ctx context.Context
cc ConvertConfig
buf []byte
convertElapsed time.Duration
}
type html2image struct {
Conver
}
func (ins *html2image) GetConvertElapsed() time.Duration {
return ins.convertElapsed
}
func (ins *html2image) Convert() ([]byte, error) {
start := time.Now()
defer func() {
ins.convertElapsed = time.Since(start)
}()
var params Html2ImageParams
params, ok := ins.cc.Params.(Html2ImageParams)
if !ok {
return nil, errors.New("wrong html2image params given")
}
ctx, cancel := chromedp.NewContext(ins.ctx)
defer cancel()
if err := chromedp.Run(ctx,
chromedp.Navigate(ins.cc.Url),
chromedp.Sleep(time.Duration(params.WaitingTime)*time.Millisecond),
chromedp.ActionFunc(func(ctx context.Context) error {
if !params.CustomClip {
// get layout metrics
_, _, contentSize, _, _, _, err := page.GetLayoutMetrics().Do(ctx)
if err != nil {
return err
}
params.Clip.X = contentSize.X
params.Clip.Y = contentSize.Y
params.Clip.Width = contentSize.Width
params.Clip.Height = contentSize.Height
}
// force viewport emulation
err := emulation.SetDeviceMetricsOverride(int64(params.Clip.Width), int64(params.Clip.Height), 1, false).
WithScreenOrientation(&emulation.ScreenOrientation{
Type: emulation.OrientationTypePortraitPrimary,
Angle: 0,
}).
Do(ctx)
if err != nil {
return err
}
// capture screenshot
ins.buf, err = params.Do(ctx)
return err
}),
); err != nil {
return nil, err
}
return ins.buf, nil
}
func GetImg(url, filename string) error {
result := DoctronConfig{}
requestDTO := newDefaultHtml2ImageRequestDTO()
result.Url = requestDTO.Url
ins := new(html2image)
ins.Conver = Conver{
ctx: context.Background(),
cc: ConvertConfig{
Url: url,
Params: convertToHtml2ImageParams(requestDTO),
},
}
img, err := ins.Convert()
if err != nil {
fmt.Println("err", err)
return err
}
err = os.WriteFile(filename, img, 0666)
if err != nil {
fmt.Println("err", err)
return err
}
return nil
}

@ -0,0 +1,9 @@
package html2Img
import (
"testing"
)
func Test_html2image(t *testing.T) {
GetImg("https://www.baidu.com", "test.webp")
}

@ -0,0 +1,16 @@
module html2Img
go 1.19
require (
github.com/chromedp/cdproto v0.0.0-20220804213442-94946ca6fcf8 // indirect
github.com/chromedp/chromedp v0.8.3 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)

@ -0,0 +1,3 @@
html 2 img
[]: # Language: markdown
[]: # Path: readme.md
Loading…
Cancel
Save