|
|
|
@ -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
|
|
|
|
|
}
|