在 Java 中通过套接字发送图像的有效方法

2024-01-19

我是一个 Java 菜鸟,我已经阅读了一些有关套接字的基础知识,并且我可以使用 ImageIO 通过套接字成功发送图像,但我想减少发送的数据量。最终,我希望以尽可能小的文件大小尽快发送图像(屏幕截图)。

现在,我已经这样设置了 imageIO ;

DataInputStream in=new DataInputStream(client.getInputStream());

DataOutputStream out = new DataOutputStream(client.getOutputStream());

ImageIO.write(captureImg(),"JPG",client.getOutputStream());

和接收者:

BufferedImage img=ImageIO.read(ImageIO.createImageInputStream(server.getInputStream()));

File outputfile = new File("Screen"+(date.toString())+".jpg");

ImageIO.write(img, "jpg", outputfile);

如果您想知道,这是我用来拍摄图像的方法。

Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());              
BufferedImage capture = new Robot().createScreenCapture(screenRect);

我听说过字节数组,您可以在其中发送字节,然后在另一端绘制图像。但是我不确定这是否更有效。

任何帮助将不胜感激,请询问您是否希望我为字节数组添加任何额外的信息或代码!

Thanks.

编辑:帕特里克:

ByteArrayOutputStream bScrn = new ByteArrayOutputStream(); 
ImageIO.write(captureImg(), "JPG", bScrn); 
byte imgBytes[] = bScrn.toByteArray();


out.write((Integer.toString(imgBytes.length)).getBytes());
out.write(imgBytes,0,imgBytes.length);

评论中已经进行了广泛的讨论,但总结一下我认为重要的几点:

您需要在几个标准之间进行权衡:

  • 最小化网络流量
  • 最小化CPU负载
  • 最大化图像质量

您可以通过高图像压缩来减少网络流量。但这会增加CPU负载并可能降低图像质量。

是否降低图像质量取决于压缩类型:对于JPG,您可以将图像任意小,但是图像的质量将......好吧,任意差。对于 PNG,图像质量将保持不变(因为它是无损压缩),但 CPU 负载和生成的图像大小可能会更大。

还提到了压缩图像数据的选项。确实,压缩图像的 JPG 或 PNG 数据几乎不会减少数据量(因为数据已经is压缩)。但压缩raw图像数据是一种可行的选择,可以替代 JPG 或 PNG。

哪种压缩技术(JPG、PNG 或 ZIP)合适还取决于图像content:JPG 更适合“自然”图像,例如照片或渲染图像。它们可以承受高压缩而不会造成伪影。对于人造图像(如线条图),它很快就会产生不良的伪影,特别是在锐利边缘或图像包含文本时。与此相反:当图像包含单一颜色的大区域时,由于这些压缩方法的“运行长度压缩”性质,像 PNG(或 ZIP)这样的压缩可以减小图像大小。

我很早之前就已经对这种图像传输进行了一些实验,并以一种可以轻松调整这些参数并在不同方法之间切换以及比较不同应用案例的速度的方式实现它。但从我的头脑中,我无法对结果进行深刻的总结。

顺便说一句:取决于what如果您确实想要传输,您可以考虑使用与以下技术不同的技术来获取图像数据:Robot#createScreenCapture(Rectangle)。众所周知,这种方法速度慢得令人痛苦。例如,当您想要传输 Swing 应用程序时,您可以让您的应用程序直接绘制到图像中。大致有这样的模式

BufferedImage image = new BufferedImage(w,h,type);
Graphics g = image.getGraphics();
myMainFrame.paint(g);
g.dispose();

(这是only草图,展示基本想法!)

此外,您可以考虑其他选项来提高此类图像传输的“感知速度”。例如,您可以将图像分为tiles,然后将这些瓷砖依次转移。如果图像尽快至少部分可见,接收者可能会感激。这个想法可以进一步延伸。例如,通过检测两帧之间哪些图块确实发生了变化,并且仅传输这些变化的图块。 (这种方法可以通过检测必须转移的“最小区域”以相当复杂的方式扩展和实施)

但是,对于您首先想要使用最明显的调整参数的情况:以下是一种允许将质量值在 0.0 到 1.0 之间的 JPG 图像写入输出流的方法:

public static void writeJPG(
    BufferedImage bufferedImage,
    OutputStream outputStream,
    float quality) throws IOException
{
    Iterator<ImageWriter> iterator =
        ImageIO.getImageWritersByFormatName("jpg");
    ImageWriter imageWriter = iterator.next();
    ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
    imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    imageWriteParam.setCompressionQuality(quality);
    ImageOutputStream imageOutputStream =
        new MemoryCacheImageOutputStream(outputStream);
    imageWriter.setOutput(imageOutputStream);
    IIOImage iioimage = new IIOImage(bufferedImage, null, null);
    imageWriter.write(null, iioimage, imageWriteParam);
    imageOutputStream.flush();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Java 中通过套接字发送图像的有效方法 的相关文章

随机推荐

  • Laravel 路由不调用控制器的功能

    我在页面 刀片 中有一个表单 它重定向到一个路由 该路由要调用控制器中的函数 但它甚至不会进入函数内部 因为即使是简单的 dd 不能被执行 在途中 如果我更改为 Route post edit profile function Reques
  • 无法使用自定义样式编织为 pdf

    尝试使用自定义 mystyles sty 文件从 RStudio 编织为 pdf 这曾经工作正常 但现在我已经升级到 RStudio 1 044 我收到错误 Example title Test output pdf document in
  • 分析(可能受 I/O 限制)进程以减少延迟

    我想提高大型应用程序中特定方法的性能 目标是改善延迟 特定功能所花费的挂钟时间 而不是 必然 系统负载 要求 由于我预计大部分延迟是由 I O 造成的 因此请考虑等待 阻塞所花费的时间 换句话说 查看挂钟时间而不是 CPU 时间 由于该程序
  • 已解析的依赖项中存在不兼容的版本

    我正在尝试运行我的 python 项目 该项目似乎在我的 Mac 上运行良好 在 pycharm 中最好 不太好 但可以在 VSCode 中运行 但在 VSCode 中的树莓派上运行得很糟糕 每当我运行pipenv shell然后一个pip
  • StepFunction 的 Choice 规则检查数组字段是否为空

    有没有办法在 Step Function 中创建选择规则来确定数组字段是否有元素 当前 StepFunction 文档 https docs aws amazon com step functions latest dg amazon st
  • 在 C 和 C++ 中 main() 应该返回什么?

    定义的正确 最有效 方法是什么main C 和 C 中的函数 int main or void main 为什么 那么论点又如何呢 如果int main then return 1 or return 0 返回值为main指示程序如何退出
  • 使用蓝牙在其他 iOS 设备上拍照

    如果有 iOS 蓝牙经验的人可以向我展示如何使用蓝牙类在其他 iOS 设备上拍照 我将不胜感激 该应用程序允许用户登录 注册 然后拍摄并上传照片 http www raywenderlich com 13511 how to create
  • 使用 PHP 将特殊字符转换为普通字符,例如将 ã、é、ç 转换为 a、e、c [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想使用 PHP 将特殊字符转换为普
  • UNIX 命令 mv 和 rm 如何处理打开的文件?

    如果我正在读取存储在 NTFS 文件系统上的文件 并且尝试在读取该文件时移动 重命名该文件 我将无法这样做 如果我在 UNIX 文件系统 例如 EXT3 上尝试此操作 它会成功 并且执行读取的进程不受影响 我什至可以 rm 文件并且读取过程
  • 有没有办法保护Python eval 的字符串?

    关于使用Python的eval有很多问题不安全的字符串 eg Python eval 在不受信任的字符串上的安全性 https stackoverflow com questions 661084 security of pythons e
  • 比较序言中两个列表的内容

    我正在做一些家庭作业 但我被困在一个点上 我得到了一些这样的事实 word h e l lo word m a n word w o m a n etc 我必须制定一条规则 以便用户输入一个字母列表 我应该将该列表与我拥有的单词进行比较并纠
  • 如何生成重复字符的排列

    我基本上想创建由三个操作符号组成的字符串 例如 or or 这些字符串中的每一个都应该被推入vector
  • 将 Rails 中的日期时间字符串转换为 UTC

    我有一个像这样的字符串 2010 01 01 12 30 00 我需要将当前本地时区转换为 UTC 我尝试了这个 但似乎认为该字符串已经是 UTC 2010 01 01 12 30 00 to datetime in time zone C
  • MVC4 通过 Ajax.BeginForm 传递模型

    我尝试过遵循一些好帖子 https stackoverflow com questions 5410055 using ajax beginform with asp net mvc 3 razor在这里让它工作 但每次我单击 ajax 回
  • 某些页面上有 https 请求,但并非所有页面上都有 https 请求 zend Framework

    我需要将 https 放在某些 URL 上 但不是所有 URL 上 我正在使用 zend URl view helper 来查看所有链接 我有一个用于整个网站的 example com SSL 证书 现在我打开网站https www exa
  • 与 os.scandir() 引发 AttributeError: __exit__

    An AttributeError当我使用 python 文档中的示例代码时引发 here https docs python org 3 library os html os scandir 示例代码如下 with os scandir
  • ViewPager 或 ScrollView 中的 WebView - Android 3.0+ 上奇怪的渲染错误

    我有一个 ViewPager ViewPager的每一页都是一个ScrollView ScrollView 包含一个 WebView 和几个其他视图 在 Android 2 3 及更早版本上一切正常 但在 3 0 上有一个奇怪的渲染问题 在
  • 制作远程 git 存储库的本地副本

    我对版本控制的术语或实践和程序不是很熟悉 这就是我想做的 我想从互联网上的 git 存储库下载一个文件夹 克隆是正确的方法吗 克隆不会保留不必要的元数据文件吗 有没有办法进行 干净 下载 我想设置一个包含此文件夹的本地存储库 我现在可以在其
  • 当ant运行在JDK1.6中时如何将类编译到JDK1.5

    我的开发环境运行在JDK1 6中 我需要编译一些类 以便它们与运行JDK1 5的客户端兼容 我该如何使用 javac ant 目标来做到这一点 命令行 javac target 1 5 源文件 Ant lt javac srcdir src
  • 在 Java 中通过套接字发送图像的有效方法

    我是一个 Java 菜鸟 我已经阅读了一些有关套接字的基础知识 并且我可以使用 ImageIO 通过套接字成功发送图像 但我想减少发送的数据量 最终 我希望以尽可能小的文件大小尽快发送图像 屏幕截图 现在 我已经这样设置了 imageIO