C++ 之间的图像传输和 Java 通过 Socket

发布于 2024-09-19 19:00:08 字数 347 浏览 4 评论 0原文

我想将图像从 Java 应用程序传输到 C++ 应用程序。我使用套接字作为通信方法,目前这对于字符串来说效果很好。

我希望能够双向传输(Java <-> C++)。

图像不是文件,这是一个内存对象/结构。所以我的主要问题是如何对图像进行编码以进行传输,以便它可以在Java和C++中使用。

传输在同一台机器上(没有网络,因此速度并不重要),但仍然越快/越高效越好。

谢谢

注意:我在 C++ 中使用 OpenCV,主要目标是处理网络摄像头流。我不/不能使用 JavaCV 或类似的东西!

I would like to transfer an image from a Java application to a C++ application. I am using sockets as the communication method, and for now this works good with strings.

I want to be able to transmit it both way (Java <-> C++).

The image is NOT a file, this is a memory object/structure. So my main problem is how to encode the image for the transmission, so that it can be used in Java and in C++.

The transfer is on the same machine (no network, so the speed isn't critical), but still the faster/more efficient, the better.

Thank you

Note : I am using OpenCV in C++, and the main goal is to process a webcam stream. I don't / can't use JavaCV or something like that !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

任谁 2024-09-26 19:00:08

发送 RGB 字节怎么样?您可以从 BufferedImage 获取 RGB 字节,然后将其作为字节数组发送到 C++ 层。然后在 C++ 层中使用该字节数组构造回图像。

How about sending the RGB bytes. You can get the RGB bytes from BufferedImage and then send it to your C++ layer as a byte array. And then in the C++ layer construct back the the image using that byte array.

岛徒 2024-09-26 19:00:08

使用高效的跨语言数据交换格式(例如 Google protobuf)可能是一种解决方案。 protobuf 允许您像这样交换图像对象:

// Java image class

class Image {
    // ...
    byte[] getImageData() {
        return imageData_;
    }

    int getVersion() {
        return version_;
    }
    // ...
}

图像对象可以使用以下 protobuf 消息进行序列化:

message ImageMsg {
    required int32 version = 1;
    required bytes imageData = 2;
}

protobuf 编译器将从该定义生成 Java 和 C++ 类。在 Java 中,将图像序列化为 ImageMsg 对象:

Image img;
// ...
ImageMsg.Builder msg = ImageMsg.newBuilder();
msg.setVersion(img.getVersion());
msg.setImageData(img.getImageData());
// The output stream could point to a file, socket, pipe or something else.
msg.writeTo(someOutputStream);

在 C++ 端,从流中读回对象:

std::istream* is;
// initialize istream

ImageMsg msg;    
msg.ParseFromIstream(istream);
Image img(msg.getVersion(), msg.getImageData());

也可以执行相反的操作,即将图像对象从 C++ 发送到 Java。

Using an efficient, cross-language data interchange format like Google protobuf, might be a solution. protobuf allows you to interchange image objects like this:

// Java image class

class Image {
    // ...
    byte[] getImageData() {
        return imageData_;
    }

    int getVersion() {
        return version_;
    }
    // ...
}

Image objects could be serialized using the following protobuf message:

message ImageMsg {
    required int32 version = 1;
    required bytes imageData = 2;
}

The protobuf compiler will generate Java and C++ classes from this definition. From Java you serialize an Image as an ImageMsg object:

Image img;
// ...
ImageMsg.Builder msg = ImageMsg.newBuilder();
msg.setVersion(img.getVersion());
msg.setImageData(img.getImageData());
// The output stream could point to a file, socket, pipe or something else.
msg.writeTo(someOutputStream);

On the C++ side, read back the object from the stream:

std::istream* is;
// initialize istream

ImageMsg msg;    
msg.ParseFromIstream(istream);
Image img(msg.getVersion(), msg.getImageData());

It is also possible to do the reverse, i.e, send the image object from C++ to Java.

﹏半生如梦愿梦如真 2024-09-26 19:00:08

您应该使用常见的便携式图像格式(例如 .png、.gif、.jpg、.bmp),记住其中一些格式是有损的,否则您应该发送原始像素数据。如果您发送原始数据,那么您还必须确保两端都知道图像的高度和宽度以及像素格式(即通道 R、G、B 和可能的 A 的顺序,以及位数对于每个)。也许您需要将其作为消息的一部分进行传达,但也许对于您的应用程序来说,其中一些内容始终是相同的。

You should either use a common portable image format (such as .png, .gif, .jpg, .bmp), bearing in mind that some of those are lossy, or else you should send raw pixel data. If you send raw data, then you'll also have to make sure both ends know the image height and width, and the pixel format (that is, the order of channels R, G, B and possibly A, and the number of bits for each). Maybe you need to communicate that as part of the message, but maybe for your application some of those things are always the same.

-小熊_ 2024-09-26 19:00:08

您可以将图像转换为字节数组或 Base64 编码字符串,然后在两个应用程序之间传递
这是如何在 C++ 中使用 opencv 将 cv::Mat 编码为 std::string 的示例

std::vector<uchar> buf;
cv::imencode(".jpg", frame, buf); //you can use other extensions read more into cv::imencode to find the best one for you.
auto *enc_msg = reinterpret_cast<unsigned char*>(buf.data());
std::string encoded = base64_encode(enc_msg, buf.size());

base64_encode 是我正在使用的 websocket 库提供的函数,但我相信有一个名为 base64 的标头
你可以做一些谷歌搜索,你会找到这样的功能。

You can either convert the image to a byte array or to a base64 encoded string and pass it between the two apps
here is an example of how to encode a cv::Mat to a std::string using opencv in C++

std::vector<uchar> buf;
cv::imencode(".jpg", frame, buf); //you can use other extensions read more into cv::imencode to find the best one for you.
auto *enc_msg = reinterpret_cast<unsigned char*>(buf.data());
std::string encoded = base64_encode(enc_msg, buf.size());

base64_encode is a function provided by the websocket library I was using but I believe there is a header called base64 for that
you can do a little google search and you'd find such function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文