From f0ac7a753aa00b59a816e31c3fb35006c66c7c32 Mon Sep 17 00:00:00 2001 From: Nanubala Gnana Sai <45007169+jonpsy@users.noreply.github.com> Date: Tue, 30 Nov 2021 06:37:35 +0000 Subject: [PATCH 1/2] Encode to png for Framebuffer. --- .../examples/task/vision/desktop/utils/BUILD | 1 + .../task/vision/desktop/utils/image_utils.cc | 48 +++++++++++++++++++ .../task/vision/desktop/utils/image_utils.h | 6 +++ 3 files changed, 55 insertions(+) diff --git a/tensorflow_lite_support/examples/task/vision/desktop/utils/BUILD b/tensorflow_lite_support/examples/task/vision/desktop/utils/BUILD index 481fd8ecf..0e8a5002a 100644 --- a/tensorflow_lite_support/examples/task/vision/desktop/utils/BUILD +++ b/tensorflow_lite_support/examples/task/vision/desktop/utils/BUILD @@ -16,6 +16,7 @@ cc_library( "//tensorflow_lite_support/cc/port:integral_types", "//tensorflow_lite_support/cc/port:status_macros", "//tensorflow_lite_support/cc/port:statusor", + "//tensorflow_lite_support/cc/task/vision/core:frame_buffer", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", diff --git a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc index 6f3aa737b..e4153f72a 100644 --- a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc +++ b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc @@ -87,6 +87,54 @@ absl::Status EncodeImageToPngFile(const ImageData& image_data, return absl::OkStatus(); } +absl::Status EncodeImageToPngFile(const FrameBuffer& image_buffer, + const std::string& image_path) { + + const int channels = [&image_buffer]() + { + int channels = -1; + switch(image_buffer.format()) { + case FrameBuffer::Format::kGRAY: + channels = 1; + break; + case FrameBuffer::Format::kRGB: + channels = 3; + break; + case FrameBuffer::Format::kRGBA: + channels = 4; + break; + default: + break; + } + return channels; + }(); + // Sanity check inputs. + if (image_buffer.dimension().width <= 0 || image_buffer.dimension().height <= 0) { + return absl::InvalidArgumentError( + absl::StrFormat("Expected positive image dimensions, found %d x %d.", + image_buffer.dimension().width, image_buffer.dimension().height)); + } + if (channels == -1) { + return absl::UnimplementedError( + absl::StrFormat("Expected image buffer with 1 (grayscale), 3 (RGB) or 4 " + "(RGBA) channels, found %d", + image_buffer.format())); + } + if (image_buffer.plane(0).buffer == nullptr) { + return absl::InvalidArgumentError( + "Expected plane buffer to be set, found nullptr."); + } + + if (stbi_write_png( + image_path.c_str(), image_buffer.dimension().width, image_buffer.dimension().height, + channels, image_buffer.plane(0).buffer, + /*stride_in_bytes=*/image_buffer.dimension().width * channels) == 0) { + return absl::InternalError("An error occurred while encoding image."); + } + + return absl::OkStatus(); +} + void ImageDataFree(ImageData* image) { stbi_image_free(image->pixel_data); } } // namespace vision diff --git a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h index a0b0c6bba..b0a7b7dea 100644 --- a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h +++ b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.h @@ -19,6 +19,7 @@ limitations under the License. #include "absl/strings/string_view.h" // from @com_google_absl #include "tensorflow_lite_support/cc/port/integral_types.h" #include "tensorflow_lite_support/cc/port/statusor.h" +#include "tensorflow_lite_support/cc/task/vision/core/frame_buffer.h" namespace tflite { namespace task { @@ -48,6 +49,11 @@ tflite::support::StatusOr DecodeImageFromFile( absl::Status EncodeImageToPngFile(const ImageData& image_data, const std::string& image_path); +// Encodes the image provided as an FrameBuffer as lossless PNG to the provided +// path. +absl::Status EncodeImageToPngFile(const FrameBuffer& image_buffer, + const std::string& image_path); + // Releases image pixel data memory. void ImageDataFree(ImageData* image); From a3481a5a11b6cf864311710d30ecedb933e691fe Mon Sep 17 00:00:00 2001 From: Nanubala Gnana Sai <45007169+jonpsy@users.noreply.github.com> Date: Fri, 3 Dec 2021 15:20:51 +0530 Subject: [PATCH 2/2] Update image_utils.cc Use return. --- .../task/vision/desktop/utils/image_utils.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc index e4153f72a..18f56c7a5 100644 --- a/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc +++ b/tensorflow_lite_support/examples/task/vision/desktop/utils/image_utils.cc @@ -92,21 +92,16 @@ absl::Status EncodeImageToPngFile(const FrameBuffer& image_buffer, const int channels = [&image_buffer]() { - int channels = -1; switch(image_buffer.format()) { case FrameBuffer::Format::kGRAY: - channels = 1; - break; + return 1; case FrameBuffer::Format::kRGB: - channels = 3; - break; + return 3; case FrameBuffer::Format::kRGBA: - channels = 4; - break; + return 4; default: - break; + return -1; } - return channels; }(); // Sanity check inputs. if (image_buffer.dimension().width <= 0 || image_buffer.dimension().height <= 0) {