From d1241790cbc9fd52d91170c6b91f6a68ee010aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E7=85=AE=E7=89=9B=E8=82=89?= Date: Mon, 12 Apr 2021 15:29:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ocr=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20(#388)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qiq@pvc123.com --- officialaccount/ocr/ocr.go | 287 +++++++++++++++++++++++++++++ officialaccount/officialaccount.go | 7 + 2 files changed, 294 insertions(+) create mode 100644 officialaccount/ocr/ocr.go diff --git a/officialaccount/ocr/ocr.go b/officialaccount/ocr/ocr.go new file mode 100644 index 0000000..c1521f8 --- /dev/null +++ b/officialaccount/ocr/ocr.go @@ -0,0 +1,287 @@ +package ocr + +import ( + "fmt" + "net/url" + + "github.com/silenceper/wechat/v2/officialaccount/context" + "github.com/silenceper/wechat/v2/util" +) + +const ( + ocrIDCardURL = "https://api.weixin.qq.com/cv/ocr/idcard" + ocrBankCardURL = "https://api.weixin.qq.com/cv/ocr/bankcard" + ocrDrivingURL = "https://api.weixin.qq.com/cv/ocr/driving" + ocrDrivingLicenseURL = "https://api.weixin.qq.com/cv/ocr/drivinglicense" + ocrBizLicenseURL = "https://api.weixin.qq.com/cv/ocr/bizlicense" + ocrCommonURL = "https://api.weixin.qq.com/cv/ocr/comm" + ocrPlateNumberURL = "https://api.weixin.qq.com/cv/ocr/platenum" +) + +//OCR struct +type OCR struct { + *context.Context +} + +//coordinate 坐标 +type coordinate struct { + X int64 `json:"x,omitempty"` + Y int64 `json:"y,omitempty"` +} + +//position 位置 +type position struct { + LeftTop coordinate `json:"left_top"` + RightTop coordinate `json:"right_top"` + RightBottom coordinate `json:"right_bottom"` + LeftBottom coordinate `json:"left_bottom"` +} + +//imageSize 图片尺寸 +type imageSize struct { + Width int64 `json:"w,omitempty"` + Height int64 `json:"h,omitempty"` +} + +//ResDriving 行驶证返回结果 +type ResDriving struct { + util.CommonError + + PlateNumber string `json:"plate_num,omitempty"` + VehicleType string `json:"vehicle_type,omitempty"` + Owner string `json:"owner,omitempty"` + Address string `json:"addr,omitempty"` + UseCharacter string `json:"use_character,omitempty"` + Model string `json:"model,omitempty"` + Vin string `json:"vin,omitempty"` + EngineNumber string `json:"engine_num,omitempty"` + RegisterDate string `json:"register_date,omitempty"` + IssueDate string `json:"issue_date,omitempty"` + PlateNumberB string `json:"plate_num_b,omitempty"` + Record string `json:"record,omitempty"` + PassengersNumber string `json:"passengers_num,omitempty"` + TotalQuality string `json:"total_quality,omitempty"` + PrepareQuality string `json:"prepare_quality,omitempty"` + OverallSize string `json:"overall_size,omitempty"` + CardPositionFront map[string]position `json:"card_position_front,omitempty"` + CardPositionBack map[string]position `json:"card_position_back,omitempty"` + ImageSize imageSize `json:"img_size,omitempty"` +} + +//ResIDCard 身份证返回结果 +type ResIDCard struct { + util.CommonError + + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + ID string `json:"id,omitempty"` + Address string `json:"addr,omitempty"` + Gender string `json:"gender,omitempty"` + Nationality string `json:"nationality,omitempty"` + ValidDate string `json:"valid_date,omitempty"` +} + +//ResBankCard 银行卡返回结果 +type ResBankCard struct { + util.CommonError + + Number string `json:"number,omitempty"` +} + +//ResDrivingLicense 驾驶证返回结果 +type ResDrivingLicense struct { + util.CommonError + + IDNumber string `json:"id_num,omitempty"` + Name string `json:"name,omitempty"` + Sex string `json:"sex,omitempty"` + Nationality string `json:"nationality,omitempty"` + Address string `json:"address,omitempty"` + Birthday string `json:"birth_date,omitempty"` + IssueDate string `json:"issue_date,omitempty"` + CarClass string `json:"car_class,omitempty"` + ValidFrom string `json:"valid_from,omitempty"` + ValidTo string `json:"valid_to,omitempty"` + OfficialSeal string `json:"official_seal,omitempty"` +} + +//ResBizLicense 营业执照返回结果 +type ResBizLicense struct { + util.CommonError + + RegisterNumber string `json:"reg_num,omitempty"` + Serial string `json:"serial,omitempty"` + LegalRepresentative string `json:"legal_representative,omitempty"` + EnterpriseName string `json:"enterprise_name,omitempty"` + TypeOfOrganization string `json:"type_of_organization,omitempty"` + Address string `json:"address,omitempty"` + TypeOfEnterprise string `json:"type_of_enterprise,omitempty"` + BusinessScope string `json:"business_scope,omitempty"` + RegisteredCapital string `json:"registered_capital,omitempty"` + PaidInCapital string `json:"paid_in_capital,omitempty"` + ValidPeriod string `json:"valid_period,omitempty"` + RegisterDate string `json:"registered_date,omitempty"` + CertPosition map[string]position `json:"cert_position,omitempty"` + ImageSize imageSize `json:"img_size,omitempty"` +} + +//ResCommon 公共印刷品返回结果 +type ResCommon struct { + util.CommonError + + Items []commonItem `json:"items,omitempty"` + ImageSize imageSize `json:"img_size,omitempty"` +} + +//commonItem 公共元素 +type commonItem struct { + Position position `json:"pos"` + Text string `json:"text"` +} + +//ResPlateNumber 车牌号返回结果 +type ResPlateNumber struct { + util.CommonError + + Number string `json:"number"` +} + +//NewOCR 实例 +func NewOCR(c *context.Context) *OCR { + ocr := new(OCR) + ocr.Context = c + return ocr +} + +//IDCard 身份证OCR识别接口 +func (ocr *OCR) IDCard(path string) (ResIDCard ResIDCard, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrIDCardURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResIDCard, "OCRIDCard") + + return +} + +//BankCard 银行卡OCR识别接口 +func (ocr *OCR) BankCard(path string) (ResBankCard ResBankCard, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrBankCardURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResBankCard, "OCRBankCard") + + return +} + +//Driving 行驶证OCR识别接口 +func (ocr *OCR) Driving(path string) (ResDriving ResDriving, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrDrivingURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResDriving, "OCRDriving") + + return +} + +//DrivingLicense 驾驶证OCR识别接口 +func (ocr *OCR) DrivingLicense(path string) (ResDrivingLicense ResDrivingLicense, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrDrivingLicenseURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResDrivingLicense, "OCRDrivingLicense") + + return +} + +//BizLicense 营业执照OCR识别接口 +func (ocr *OCR) BizLicense(path string) (ResBizLicense ResBizLicense, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrBizLicenseURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResBizLicense, "OCRBizLicense") + + return +} + +//Common 通用印刷体OCR识别接口 +func (ocr *OCR) Common(path string) (ResCommon ResCommon, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrCommonURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResCommon, "OCRCommon") + + return +} + +//PlateNumber 车牌OCR识别接口 +func (ocr *OCR) PlateNumber(path string) (ResPlateNumber ResPlateNumber, err error) { + accessToken, err := ocr.GetAccessToken() + if err != nil { + return + } + + uri := fmt.Sprintf("%s?img_url=%s&access_token=%s", ocrPlateNumberURL, url.QueryEscape(path), accessToken) + + response, err := util.HTTPPost(uri, "") + if err != nil { + return + } + + err = util.DecodeWithError(response, &ResPlateNumber, "OCRPlateNumber") + + return +} diff --git a/officialaccount/officialaccount.go b/officialaccount/officialaccount.go index ff5b399..5c48c75 100644 --- a/officialaccount/officialaccount.go +++ b/officialaccount/officialaccount.go @@ -3,6 +3,8 @@ package officialaccount import ( "net/http" + "github.com/silenceper/wechat/v2/officialaccount/ocr" + "github.com/silenceper/wechat/v2/officialaccount/datacube" "github.com/silenceper/wechat/v2/credential" @@ -113,3 +115,8 @@ func (officialAccount *OfficialAccount) GetBroadcast() *broadcast.Broadcast { func (officialAccount *OfficialAccount) GetDataCube() *datacube.DataCube { return datacube.NewCube(officialAccount.ctx) } + +//GetOCR OCR接口 +func (officialAccount *OfficialAccount) GetOCR() *ocr.OCR { + return ocr.NewOCR(officialAccount.ctx) +}