1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

support: image ocr.

This commit is contained in:
Mrs4s 2020-09-21 21:43:33 +08:00
parent 420fd0746a
commit ab2038a087
4 changed files with 94 additions and 0 deletions

View File

@ -1146,6 +1146,32 @@ func (c *QQClient) buildGroupFileDownloadReqPacket(groupCode int64, fileId strin
return seq, packet
}
// OidbSvc.0xe07_0
func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, height int32) (uint16, []byte) {
seq := c.nextSeq()
body := &oidb.DE07ReqBody{
Version: 1,
Entrance: 3,
OcrReqBody: &oidb.OCRReqBody{
ImageUrl: url,
OriginMd5: md5,
AfterCompressMd5: md5,
AfterCompressFileSize: size,
AfterCompressWeight: weight,
AfterCompressHeight: height,
IsCut: false,
},
}
b, _ := proto.Marshal(body)
req := &oidb.OIDBSSOPkg{
Command: 3591,
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0xe07_0", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
// PttCenterSvr.ShortVideoDownReq
func (c *QQClient) buildPttShortVideoDownReqPacket(uuid, md5 []byte) (uint16, []byte) {
seq := c.nextSeq()

View File

@ -142,6 +142,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
"MultiMsg.ApplyDown": decodeMultiApplyDownResponse, // 长消息/合并转发请求下载包
"OidbSvc.0x6d6_2": decodeOIDB6d6Response, // 群文件操作包
"OidbSvc.0x88d_0": decodeGroupInfoResponse, // 获取群资料包
"OidbSvc.0xe07_0": decodeImageOcrResponse, // 图片OCR请求包
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse, // 获取用户卡片资料包
"PttCenterSvr.ShortVideoDownReq": decodePttShortVideoDownResponse, // 短视频下载请求包
"LightAppSvc.mini_app_info.GetAppInfoById": decodeAppInfoResponse, // 获取小程序资料包
@ -624,6 +625,24 @@ func (c *QQClient) uploadPrivateImage(target int64, img []byte, count int) (*mes
return e, nil
}
func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
switch e := img.(type) {
case *message.GroupImageElement:
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.Url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
if err != nil {
return nil, err
}
return rsp.(*OcrResponse), nil
case *message.ImageElement:
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.Url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
if err != nil {
return nil, err
}
return rsp.(*OcrResponse), nil
}
return nil, errors.New("image error")
}
func (c *QQClient) UploadGroupPtt(groupCode int64, voice []byte) (*message.GroupVoiceElement, error) {
h := md5.Sum(voice)
seq, pkt := c.buildGroupPttStorePacket(groupCode, h[:], int32(len(voice)), 0, int32(len(voice)))

View File

@ -1009,6 +1009,39 @@ func decodeOIDB6d6Response(c *QQClient, _ uint16, payload []byte) (interface{},
return fmt.Sprintf("http://%s/ftn_handler/%s/", ip, url), nil
}
func decodeImageOcrResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
pkg := oidb.OIDBSSOPkg{}
rsp := oidb.DE07RspBody{}
if err := proto.Unmarshal(payload, &pkg); err != nil {
return nil, err
}
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
return nil, err
}
if rsp.Wording != "" {
return nil, errors.New(rsp.Wording)
}
var texts []*TextDetection
for _, text := range rsp.OcrRspBody.TextDetections {
var points []*Coordinate
for _, c := range text.Polygon.Coordinates {
points = append(points, &Coordinate{
X: c.X,
Y: c.Y,
})
}
texts = append(texts, &TextDetection{
Text: text.DetectedText,
Confidence: text.Confidence,
Coordinates: points,
})
}
return &OcrResponse{
Texts: texts,
Language: rsp.OcrRspBody.Language,
}, nil
}
func decodePttShortVideoDownResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
rsp := pttcenter.ShortVideoRspBody{}
if err := proto.Unmarshal(payload, &rsp); err != nil {

View File

@ -183,6 +183,22 @@ type (
Friend *FriendInfo
}
OcrResponse struct {
Texts []*TextDetection `json:"'texts'"`
Language string `json:"language"`
}
TextDetection struct {
Text string `json:"text"`
Confidence int32 `json:"confidence"`
Coordinates []*Coordinate `json:"coordinates"`
}
Coordinate struct {
X int32 `json:"x"`
Y int32 `json:"y"`
}
groupMemberListResponse struct {
NextUin int64
list []*GroupMemberInfo