diff --git a/components/camera/collectors.go b/components/camera/collectors.go index ab9b88f5c93..28959f3ce5a 100644 --- a/components/camera/collectors.go +++ b/components/camera/collectors.go @@ -7,12 +7,9 @@ import ( "github.com/pkg/errors" "go.viam.com/utils/trace" "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/structpb" - "google.golang.org/protobuf/types/known/wrapperspb" "go.viam.com/rdk/data" "go.viam.com/rdk/pointcloud" - "go.viam.com/rdk/utils" ) type method int64 @@ -80,58 +77,43 @@ func newReadImageCollector(resource interface{}, params data.CollectorParams) (d if err != nil { return nil, err } - // choose the best/fastest representation - mimeType := params.MethodParams["mime_type"] - if mimeType == nil { - // TODO: Potentially log the actual mime type at collector instantiation or include in response. - strWrapper := wrapperspb.String(utils.MimeTypeJPEG) - mimeType, err = anypb.New(strWrapper) - if err != nil { - return nil, err - } - } - - var mimeStr string - // For backwards compatibility - allow string (old behavior) and Value (new behavior) types - strVal := &wrapperspb.StringValue{} - if err := mimeType.UnmarshalTo(strVal); err == nil { - mimeStr = strVal.Value - } else { - // If that fails, try to unmarshal as Value - val := &structpb.Value{} - if err := mimeType.UnmarshalTo(val); err != nil { - return nil, err - } - mimeStr = val.GetStringValue() - } - cFunc := data.CaptureFunc(func(ctx context.Context, _ map[string]*anypb.Any) (data.CaptureResult, error) { timeRequested := time.Now() var res data.CaptureResult _, span := trace.StartSpan(ctx, "camera::data::collector::CaptureFunc::ReadImage") defer span.End() - img, metadata, err := camera.Image(ctx, mimeStr, data.FromDMExtraMap) + resImgs, resMetadata, err := camera.Images(ctx, nil, data.FromDMExtraMap) if err != nil { // A modular filter component can be created to filter the readings from a component. The error ErrNoCaptureToStore // is used in the datamanager to exclude readings from being captured and stored. if errors.Is(err, data.ErrNoCaptureToStore) { return res, err } - return res, data.NewFailedToReadError(params.ComponentName, readImage.String(), err) } + var binaries []data.Binary + if len(resImgs) == 0 { + return data.NewBinaryCaptureResult(data.Timestamps{}, binaries), nil + } + img := resImgs[0] + imgBytes, err := img.Bytes(ctx) + if err != nil { + return res, data.NewFailedToReadError(params.ComponentName, getImages.String(), err) + } + annotations := img.Annotations + annotations.Classifications = append(annotations.Classifications, data.Classification{Label: img.SourceName}) + binaries = append(binaries, data.Binary{ + Annotations: annotations, + Payload: imgBytes, + MimeType: data.MimeTypeStringToMimeType(img.MimeType()), + }) - mimeType := data.CameraFormatToMimeType(utils.MimeTypeToFormat[metadata.MimeType]) ts := data.Timestamps{ TimeRequested: timeRequested, - TimeReceived: time.Now(), + TimeReceived: resMetadata.CapturedAt, } - return data.NewBinaryCaptureResult(ts, []data.Binary{{ - MimeType: mimeType, - Payload: img, - Annotations: metadata.Annotations, - }}), nil + return data.NewBinaryCaptureResult(ts, binaries), nil }) return data.NewCollector(cFunc, params) } @@ -149,6 +131,8 @@ func newGetImagesCollector(resource interface{}, params data.CollectorParams) (d resImgs, resMetadata, err := camera.Images(ctx, nil, data.FromDMExtraMap) if err != nil { + // A modular filter component can be created to filter the readings from a component. The error ErrNoCaptureToStore + // is used in the datamanager to exclude readings from being captured and stored. if errors.Is(err, data.ErrNoCaptureToStore) { return res, err }