Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/bbq/video-image/api/grpc/v1:all-srcs",
"//app/service/bbq/video-image/api/http/v1:all-srcs",
"//app/service/bbq/video-image/cmd:all-srcs",
"//app/service/bbq/video-image/conf:all-srcs",
"//app/service/bbq/video-image/dao:all-srcs",
"//app/service/bbq/video-image/model:all-srcs",
"//app/service/bbq/video-image/server/grpc:all-srcs",
"//app/service/bbq/video-image/server/http:all-srcs",
"//app/service/bbq/video-image/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,4 @@
# v1.0.0
1. 上线功能xxx
2. 增加图片上传服务
3. merge master

View File

@@ -0,0 +1,6 @@
# Owner
daiwei
jiangdongqi
# Author
# Reviewer

View File

@@ -0,0 +1,11 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- daiwei
- jiangdongqi
labels:
- bbq
- service
- service/bbq/video-image
options:
no_parent_owners: true

View File

@@ -0,0 +1,13 @@
# video-image-service
# 项目简介
1. 提供视频截图接口
2. 判断视频是否为纯色
# 编译环境
# 依赖包
# 编译执行

View File

@@ -0,0 +1,53 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
proto_library(
name = "v1_proto",
srcs = ["api.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "v1_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
importpath = "go-common/app/service/bbq/video-image/api/grpc/v1",
proto = ":v1_proto",
tags = ["automanaged"],
deps = ["@com_github_gogo_protobuf//gogoproto:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = [],
embed = [":v1_go_proto"],
importpath = "go-common/app/service/bbq/video-image/api/grpc/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"@com_github_gogo_protobuf//gogoproto:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_x_net//context:go_default_library",
],
)

View File

@@ -0,0 +1,746 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: app/service/bbq/video-image/api/grpc/v1/api.proto
package v1
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type ImgUploadRequest struct {
Filename string `protobuf:"bytes,1,opt,name=filename,proto3" json:"filename" form:"filename"`
Dir string `protobuf:"bytes,2,opt,name=dir,proto3" json:"dir" form:"dir"`
File []byte `protobuf:"bytes,3,opt,name=file,proto3" json:"file" form:"file"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ImgUploadRequest) Reset() { *m = ImgUploadRequest{} }
func (*ImgUploadRequest) ProtoMessage() {}
func (*ImgUploadRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_api_5b020de07edc31b8, []int{0}
}
func (m *ImgUploadRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ImgUploadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ImgUploadRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *ImgUploadRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ImgUploadRequest.Merge(dst, src)
}
func (m *ImgUploadRequest) XXX_Size() int {
return m.Size()
}
func (m *ImgUploadRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ImgUploadRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ImgUploadRequest proto.InternalMessageInfo
type ImgUploadResponse struct {
Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location" form:"location"`
Etag string `protobuf:"bytes,2,opt,name=etag,proto3" json:"etag" form:"etag"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ImgUploadResponse) Reset() { *m = ImgUploadResponse{} }
func (*ImgUploadResponse) ProtoMessage() {}
func (*ImgUploadResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_api_5b020de07edc31b8, []int{1}
}
func (m *ImgUploadResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ImgUploadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ImgUploadResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *ImgUploadResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ImgUploadResponse.Merge(dst, src)
}
func (m *ImgUploadResponse) XXX_Size() int {
return m.Size()
}
func (m *ImgUploadResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ImgUploadResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ImgUploadResponse proto.InternalMessageInfo
func init() {
proto.RegisterType((*ImgUploadRequest)(nil), "bbq.service.image.v1.ImgUploadRequest")
proto.RegisterType((*ImgUploadResponse)(nil), "bbq.service.image.v1.ImgUploadResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// VideoImageClient is the client API for VideoImage service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type VideoImageClient interface {
ImgUpload(ctx context.Context, in *ImgUploadRequest, opts ...grpc.CallOption) (*ImgUploadResponse, error)
}
type videoImageClient struct {
cc *grpc.ClientConn
}
func NewVideoImageClient(cc *grpc.ClientConn) VideoImageClient {
return &videoImageClient{cc}
}
func (c *videoImageClient) ImgUpload(ctx context.Context, in *ImgUploadRequest, opts ...grpc.CallOption) (*ImgUploadResponse, error) {
out := new(ImgUploadResponse)
err := c.cc.Invoke(ctx, "/bbq.service.image.v1.VideoImage/ImgUpload", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// VideoImageServer is the server API for VideoImage service.
type VideoImageServer interface {
ImgUpload(context.Context, *ImgUploadRequest) (*ImgUploadResponse, error)
}
func RegisterVideoImageServer(s *grpc.Server, srv VideoImageServer) {
s.RegisterService(&_VideoImage_serviceDesc, srv)
}
func _VideoImage_ImgUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ImgUploadRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(VideoImageServer).ImgUpload(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/bbq.service.image.v1.VideoImage/ImgUpload",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VideoImageServer).ImgUpload(ctx, req.(*ImgUploadRequest))
}
return interceptor(ctx, in, info, handler)
}
var _VideoImage_serviceDesc = grpc.ServiceDesc{
ServiceName: "bbq.service.image.v1.VideoImage",
HandlerType: (*VideoImageServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ImgUpload",
Handler: _VideoImage_ImgUpload_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "app/service/bbq/video-image/api/grpc/v1/api.proto",
}
func (m *ImgUploadRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ImgUploadRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Filename) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.Filename)))
i += copy(dAtA[i:], m.Filename)
}
if len(m.Dir) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.Dir)))
i += copy(dAtA[i:], m.Dir)
}
if len(m.File) > 0 {
dAtA[i] = 0x1a
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.File)))
i += copy(dAtA[i:], m.File)
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *ImgUploadResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ImgUploadResponse) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Location) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.Location)))
i += copy(dAtA[i:], m.Location)
}
if len(m.Etag) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.Etag)))
i += copy(dAtA[i:], m.Etag)
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeVarintApi(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *ImgUploadRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Filename)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.Dir)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.File)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *ImgUploadResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Location)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.Etag)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovApi(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozApi(x uint64) (n int) {
return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *ImgUploadRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ImgUploadRequest{`,
`Filename:` + fmt.Sprintf("%v", this.Filename) + `,`,
`Dir:` + fmt.Sprintf("%v", this.Dir) + `,`,
`File:` + fmt.Sprintf("%v", this.File) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func (this *ImgUploadResponse) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ImgUploadResponse{`,
`Location:` + fmt.Sprintf("%v", this.Location) + `,`,
`Etag:` + fmt.Sprintf("%v", this.Etag) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringApi(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *ImgUploadRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ImgUploadRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ImgUploadRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Filename", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Filename = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Dir", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Dir = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field File", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.File = append(m.File[:0], dAtA[iNdEx:postIndex]...)
if m.File == nil {
m.File = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ImgUploadResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ImgUploadResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ImgUploadResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Location", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Location = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Etag", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Etag = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipApi(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthApi
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowApi
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipApi(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowApi = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("app/service/bbq/video-image/api/grpc/v1/api.proto", fileDescriptor_api_5b020de07edc31b8)
}
var fileDescriptor_api_5b020de07edc31b8 = []byte{
// 386 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0x3f, 0x8f, 0xda, 0x30,
0x18, 0xc6, 0x31, 0xa0, 0x0a, 0xdc, 0x4a, 0x6d, 0xa3, 0x0e, 0x08, 0xa1, 0x18, 0x79, 0x68, 0x91,
0x2a, 0x6c, 0xa5, 0x6c, 0x1d, 0x51, 0xff, 0x08, 0xa9, 0x53, 0xa4, 0xde, 0x70, 0xba, 0xc5, 0x49,
0x8c, 0xcf, 0x27, 0x82, 0x43, 0x12, 0x32, 0xdf, 0x57, 0xb8, 0x6f, 0x74, 0x23, 0xe3, 0x8d, 0x37,
0x59, 0x47, 0x46, 0x46, 0x3e, 0xc1, 0xc9, 0x26, 0x04, 0x74, 0x3a, 0xe9, 0x36, 0xbf, 0xbf, 0xf7,
0x7d, 0xfd, 0x3e, 0x8f, 0x1e, 0xe8, 0xb1, 0x24, 0xa1, 0x19, 0x4f, 0x0b, 0x19, 0x72, 0x1a, 0x04,
0x2b, 0x5a, 0xc8, 0x88, 0xab, 0xb1, 0x8c, 0x99, 0xe0, 0x94, 0x25, 0x92, 0x8a, 0x34, 0x09, 0x69,
0xe1, 0x99, 0x37, 0x49, 0x52, 0x95, 0x2b, 0xe7, 0x4b, 0x10, 0xac, 0x48, 0xb5, 0x42, 0xec, 0x20,
0x29, 0xbc, 0xfe, 0x58, 0xc8, 0xfc, 0x7a, 0x1d, 0x90, 0x50, 0xc5, 0x54, 0x28, 0xa1, 0xa8, 0x1d,
0x0e, 0xd6, 0x73, 0x5b, 0xd9, 0xc2, 0xbe, 0x0e, 0x9f, 0xe0, 0x7b, 0x00, 0x3f, 0xcd, 0x62, 0xf1,
0x3f, 0x59, 0x28, 0x16, 0xf9, 0x7c, 0xb5, 0xe6, 0x59, 0xee, 0xfc, 0x85, 0x9d, 0xb9, 0x5c, 0xf0,
0x25, 0x8b, 0x79, 0x0f, 0x0c, 0xc1, 0xa8, 0x3b, 0xfd, 0x5e, 0x6a, 0xd4, 0xf9, 0x53, 0xb1, 0x9d,
0x46, 0x75, 0x7f, 0xaf, 0xd1, 0xc7, 0xb9, 0x4a, 0xe3, 0x9f, 0xf8, 0x48, 0xb0, 0x5f, 0x37, 0x1d,
0x02, 0x5b, 0x91, 0x4c, 0x7b, 0x4d, 0xfb, 0xc7, 0xa0, 0xd4, 0xa8, 0xf5, 0x4b, 0xa6, 0x3b, 0x8d,
0x0c, 0xdd, 0x6b, 0x04, 0x0f, 0x9b, 0x91, 0x4c, 0xb1, 0x6f, 0x90, 0x33, 0x81, 0x6d, 0xb3, 0xdb,
0x6b, 0x0d, 0xc1, 0xe8, 0xc3, 0x14, 0x95, 0x1a, 0xb5, 0xcd, 0xd1, 0x9d, 0x46, 0x96, 0xef, 0x35,
0x7a, 0x7f, 0x3a, 0x86, 0x7d, 0x0b, 0xf1, 0x1d, 0x80, 0x9f, 0xcf, 0x2c, 0x64, 0x89, 0x5a, 0x66,
0xdc, 0x78, 0x58, 0xa8, 0x90, 0xe5, 0x52, 0x2d, 0xcf, 0x3d, 0xfc, 0xab, 0x98, 0xf1, 0x70, 0xec,
0x9f, 0x3c, 0x1c, 0x09, 0xf6, 0xeb, 0xa6, 0xd1, 0xc4, 0x73, 0x26, 0x2a, 0x13, 0x56, 0xd3, 0xef,
0x9c, 0x09, 0xa3, 0xc9, 0xf0, 0x93, 0x26, 0x53, 0x61, 0xdf, 0xc2, 0x1f, 0x37, 0x10, 0x5e, 0x98,
0x00, 0x67, 0x26, 0x16, 0xe7, 0x0a, 0x76, 0x6b, 0x81, 0xce, 0x57, 0xf2, 0x5a, 0x6e, 0xe4, 0x65,
0x08, 0xfd, 0x6f, 0x6f, 0xce, 0x1d, 0x9c, 0x4e, 0x07, 0x9b, 0xad, 0xdb, 0x78, 0xdc, 0xba, 0x8d,
0xdb, 0xd2, 0x05, 0x9b, 0xd2, 0x05, 0x0f, 0xa5, 0x0b, 0x9e, 0x4a, 0x17, 0x5c, 0x36, 0x0b, 0x2f,
0x78, 0x67, 0x73, 0x9e, 0x3c, 0x07, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x44, 0xc0, 0x1b, 0x61, 0x02,
0x00, 0x00,
}

View File

@@ -0,0 +1,22 @@
syntax = "proto3";
package bbq.service.image.v1;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option go_package = "v1";
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
message ImgUploadRequest {
string filename = 1 [(gogoproto.jsontag) = "filename",(gogoproto.moretags) = "form:\"filename\"",(gogoproto.customname)= "Filename"];
string dir = 2 [(gogoproto.jsontag) = "dir",(gogoproto.moretags) = "form:\"dir\"",(gogoproto.customname)= "Dir"];
bytes file = 3 [(gogoproto.jsontag) = "file",(gogoproto.moretags) = "form:\"file\"",(gogoproto.customname)= "File"];
}
message ImgUploadResponse {
string location = 1 [(gogoproto.jsontag) = "location",(gogoproto.moretags) = "form:\"location\"",(gogoproto.customname)= "Location"];
string etag = 2 [(gogoproto.jsontag) = "etag",(gogoproto.moretags) = "form:\"etag\"",(gogoproto.customname)= "Etag"];
}
service VideoImage {
rpc ImgUpload(ImgUploadRequest) returns(ImgUploadResponse);
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["api.go"],
importpath = "go-common/app/service/bbq/video-image/api/http/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,12 @@
package v1
// ScoreRequest .
type ScoreRequest struct {
Name string `json:"name" form:"name" validate:"required"`
}
// ScoreResponse .
type ScoreResponse struct {
Name string `json:"name"`
Score float32 `json:"score"`
}

View File

@@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["test.toml"],
importpath = "go-common/app/service/bbq/video-image/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/bbq/video-image/conf:go_default_library",
"//app/service/bbq/video-image/server/grpc:go_default_library",
"//app/service/bbq/video-image/server/http:go_default_library",
"//app/service/bbq/video-image/service:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,54 @@
package main
import (
"context"
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/service/bbq/video-image/conf"
"go-common/app/service/bbq/video-image/server/grpc"
"go-common/app/service/bbq/video-image/server/http"
"go-common/app/service/bbq/video-image/service"
// ecode "go-common/library/ecode/tip"
"go-common/library/log"
// "go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
log.Info("start")
// dev环境先不要
// trace.Init(conf.Conf.Tracer)
// defer trace.Close()
// ecode.Init(conf.Conf.Ecode)
serv := service.New(conf.Conf)
gserv := grpc.New(conf.Conf.RPC, serv)
http.Init(conf.Conf, serv)
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
for {
s := <-c
log.Info("get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
gserv.Shutdown(ctx)
log.Info("exit")
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,65 @@
version = "0.0.1"
user = "nobody"
family = "video-image"
address = "127.0.0.1"
env = "dev"
[mysql]
addr = "127.0.0.1:3306"
dsn = "test:test@tcp(127.0.0.1:3306)/test?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"
readDSN = ["test:test@tcp(127.0.0.2:3306)/test? timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4","test:test@tcp(127.0.0.3:3306)/test?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"]
active = 20
idle = 10
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[bm]
[bm.server]
addr = "0.0.0.0:9018"
timeout = "1s"
[bm.client]
key = "654af11b5df0c9d3"
secret = "a7512b8b243b82f4bdb72cf2824b3f8e"
dial = "500ms"
timeout = "30s"
keepAlive = "60s"
timer = 10
[bm.client.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[redis]
name = "video-image-service"
proto = "tcp"
addr = ""
idle = 10
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "1m"
[memcache]
name = "video-image-service"
proto = "tcp"
addr = ""
active = 50
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "24h"
[log]
# dir = "/tmp/log/bbq"
stdout = true
[url]
uatuploadimg = "http://uat-api.bilibili.co/x/internal/upload"
uploadimg = "http://api.bilibili.co/x/internal/upload"
api="http://api.bilibili.co"

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/bbq/video-image/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/conf:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,91 @@
package conf
import (
"errors"
"flag"
"go-common/library/conf"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config .
type Config struct {
Log *log.Config
BM *HTTPGeneral
Verify *verify.Config
Tracer *trace.Config
Ecode *ecode.Config
RPC *warden.ServerConfig
URL map[string]string
}
//HTTPGeneral .
type HTTPGeneral struct {
Server *bm.ServerConfig
Client *bm.ClientConfig
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,29 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/service/bbq/video-image/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//app/service/bbq/video-image/conf:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,31 @@
package dao
import (
"context"
"go-common/app/service/bbq/video-image/conf"
)
// Dao dao
type Dao struct {
c *conf.Config
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
}
return
}
// Close close the resource.
func (d *Dao) Close() {
return
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
// TODO: if you need use mc,redis, please add
return nil
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["model.go"],
importpath = "go-common/app/service/bbq/video-image/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,7 @@
package model
// FopVideoCovers video cloud fop=videocovers_format response
type FopVideoCovers []struct {
Count int `json:"count"`
URLFormat string `json:"url_format"`
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "go-common/app/service/bbq/video-image/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/bbq/video-image/api/grpc/v1:go_default_library",
"//app/service/bbq/video-image/service:go_default_library",
"//library/net/rpc/warden:go_default_library",
"@org_golang_google_grpc//:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,31 @@
package grpc
import (
"context"
"go-common/app/service/bbq/video-image/api/grpc/v1"
"go-common/app/service/bbq/video-image/service"
"go-common/library/net/rpc/warden"
"google.golang.org/grpc"
)
//New 生成rpc服务
func New(conf *warden.ServerConfig, srv *service.Service) *warden.Server {
s := warden.NewServer(conf)
s.Use(middleware())
v1.RegisterVideoImageServer(s.Server(), srv)
_, err := s.Start()
if err != nil {
panic("run server failed!" + err.Error())
}
return s
}
func middleware() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
//call chain
resp, err = handler(ctx, req)
return
}
}

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["http.go"],
importpath = "go-common/app/service/bbq/video-image/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/bbq/video-image/api/grpc/v1:go_default_library",
"//app/service/bbq/video-image/api/http/v1:go_default_library",
"//app/service/bbq/video-image/conf:go_default_library",
"//app/service/bbq/video-image/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,118 @@
package http
import (
"io/ioutil"
"net/http"
grpc "go-common/app/service/bbq/video-image/api/grpc/v1"
"go-common/app/service/bbq/video-image/api/http/v1"
"go-common/app/service/bbq/video-image/conf"
"go-common/app/service/bbq/video-image/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
var (
srv *service.Service
)
// Init init
func Init(c *conf.Config, s *service.Service) {
srv = s
engine := bm.DefaultServer(c.BM.Server)
route(engine)
if err := engine.Start(); err != nil {
log.Error("bm Start error(%v)", err)
panic(err)
}
}
func route(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
g := e.Group("/bbq/internal/image")
{
g.POST("/upload", imageUpload)
g.POST("/video_cover/score", videoCoverScore)
g.POST("/upload/v2", upload)
}
}
func ping(c *bm.Context) {
if err := srv.Ping(c); err != nil {
log.Error("ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(map[string]interface{}{}, nil)
}
func videoCoverScore(c *bm.Context) {
args := &v1.ScoreRequest{}
if err := c.Bind(args); err != nil {
errors.Wrap(err, "参数验证失败")
return
}
c.Request.ParseMultipartForm(1 << 22)
f, h, err := c.Request.FormFile("file")
//参数判断
if err != nil {
log.Errorv(c, log.KV("log", "get file error"), log.KV("err", err))
err = ecode.FileNotExists
return
}
defer f.Close()
//文件大小
if h.Size > (1 << 22) {
log.Errorv(c, log.KV("log", "get file error"), log.KV("err", "file size too large"))
err = ecode.FileTooLarge
return
}
c.JSON(srv.VideoCoverScore(c, args.Name, f))
}
//internal upload
func upload(c *bm.Context) {
req := &grpc.ImgUploadRequest{}
req.Filename = c.Request.PostFormValue("filename")
req.Dir = c.Request.PostFormValue("dir")
req.File = []byte(c.Request.PostFormValue("file"))
c.JSON(srv.ImgUpload(c, req))
}
func imageUpload(c *bm.Context) {
req := &grpc.ImgUploadRequest{}
req.Filename = c.Request.PostFormValue("filename")
req.Dir = c.Request.PostFormValue("dir")
c.Request.ParseMultipartForm(1 << 22)
f, h, err := c.Request.FormFile("file")
//参数判断
if err != nil {
log.Errorv(c, log.KV("log", "get file error"), log.KV("err", err))
err = ecode.FileNotExists
return
}
defer f.Close()
//文件大小
if h.Size > (1 << 22) {
log.Errorv(c, log.KV("log", "get file error"), log.KV("err", "file size too large"))
err = ecode.FileTooLarge
return
}
req.File, err = ioutil.ReadAll(f)
// req.File = []byte(c.Request.PostFormValue("file"))
//参数判断
if err != nil {
log.Errorv(c, log.KV("log", "get file error"), log.KV("err", err))
err = ecode.FileNotExists
return
}
c.JSON(srv.ImgUpload(c, req))
}

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"score.go",
"service.go",
"upload.go",
],
importpath = "go-common/app/service/bbq/video-image/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/bbq/video-image/api/grpc/v1:go_default_library",
"//app/service/bbq/video-image/api/http/v1:go_default_library",
"//app/service/bbq/video-image/conf:go_default_library",
"//app/service/bbq/video-image/dao:go_default_library",
"//library/database/bfs:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,127 @@
package service
import (
"bytes"
"fmt"
"image"
_ "image/jpeg" // for image decode
_ "image/png"
"strconv"
)
// ImageScorer .
type ImageScorer struct {
Score float32
step int
img image.Image
gray [][]uint8
avg [][]uint8
bin [][]uint64
}
// NewImageScorer .
func NewImageScorer(img image.Image, step int) (is *ImageScorer, err error) {
is = &ImageScorer{
Score: 0,
img: img,
step: step,
}
return
}
// CompareWithPure 与纯色图片比较hash距离
func (is *ImageScorer) CompareWithPure() {
is.grayMatrix()
is.averageMatrix()
is.binaryMatrix()
hashCode := is.matrixHash()
var count float32
for i := 0; i < len(hashCode); i++ {
if hashCode[i] != byte(48) {
count++
}
}
is.Score = count / float32(len(hashCode))
}
// grayImgMatrix get gray image matrix from image.Image
func (is *ImageScorer) grayMatrix() {
bounds := is.img.Bounds()
width := bounds.Max.X
height := bounds.Max.Y
dst := make([][]uint8, height)
for i := 0; i < height; i++ {
dst[i] = make([]uint8, width)
}
// 图像的边界不一定从0,0开始
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, _ := is.img.At(x, y).RGBA()
gray16 := uint32(0.3*float32(r) + 0.59*float32(g) + 0.11*float32(b))
dst[y][x] = uint8(gray16 >> 8)
}
}
is.gray = dst
}
// averageMatrix .
func (is *ImageScorer) averageMatrix() {
dst := make([][]uint8, len(is.gray)/is.step)
for i := 0; i < len(is.gray)/is.step; i++ {
dst[i] = make([]uint8, len(is.gray[0])/is.step)
}
for i := range dst {
for j := range dst[i] {
avg := 0
xhead := i * is.step
xtail := (i + 1) * is.step
yhead := j * is.step
ytail := (j + 1) * is.step
for _, v := range is.gray[xhead:xtail] {
for _, u := range v[yhead:ytail] {
avg += int(u)
}
}
dst[i][j] = uint8(avg / is.step / is.step)
}
}
is.avg = dst
}
// binaryMatrix .
func (is *ImageScorer) binaryMatrix() {
height := len(is.avg)
width := len(is.avg[0])
dst := make([][]uint64, height)
for i := range dst {
dst[i] = make([]uint64, width)
}
for i, v := range is.avg {
x := i * is.step
for j, u := range v {
y := j * is.step
for k := 0; k < is.step; k++ {
for l := 0; l < is.step; l++ {
dst[i][j] = dst[i][j] << 1
if u < is.gray[x+k][y+l] {
dst[i][j]++
}
}
}
}
}
is.bin = dst
}
// matrixHash .
func (is *ImageScorer) matrixHash() []byte {
var buffer bytes.Buffer
for i := range is.bin {
for _, v := range is.bin[i] {
// hex := DecToHex(v)
hex := fmt.Sprintf("%016s", strconv.FormatUint(v, 16))
buffer.WriteString(hex)
}
}
return buffer.Bytes()
}

View File

@@ -0,0 +1,56 @@
package service
import (
"context"
"image"
"mime/multipart"
httpV1 "go-common/app/service/bbq/video-image/api/http/v1"
"go-common/app/service/bbq/video-image/conf"
"go-common/app/service/bbq/video-image/dao"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
return s
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}
// VideoCoverScore .
func (s *Service) VideoCoverScore(c context.Context, name string, f multipart.File) (resp *httpV1.ScoreResponse, err error) {
img, _, err := image.Decode(f)
if err != nil {
return
}
imgScorer, err := NewImageScorer(img, 100)
if err != nil {
return
}
imgScorer.CompareWithPure()
resp = &httpV1.ScoreResponse{
Name: name,
Score: imgScorer.Score,
}
return
}

View File

@@ -0,0 +1,37 @@
package service
import (
"context"
"go-common/app/service/bbq/video-image/api/grpc/v1"
"go-common/library/database/bfs"
"go-common/library/log"
)
const (
//BUCKET ...
BUCKET = "bbq"
)
//ImgUpload ...
func (s *Service) ImgUpload(ctx context.Context, req *v1.ImgUploadRequest) (rep *v1.ImgUploadResponse, err error) {
log.Info("begin imgupload")
rep = &v1.ImgUploadResponse{}
conf := &bfs.Config{
Host: s.c.URL["api"],
HTTPClient: s.c.BM.Client,
}
bfsClient := bfs.New(conf)
log.Info("bfs begin......")
bfsreq := &bfs.Request{
Bucket: BUCKET,
Dir: "/video-image/" + req.Dir,
Filename: req.Filename,
File: req.File,
}
rep.Location, err = bfsClient.Upload(context.Background(), bfsreq)
if err != nil {
log.Error("bfs failed,err:%v", err)
}
return
}