【问题标题】:Sending an image as a byte array between client and server在客户端和服务器之间将图像作为字节数组发送
【发布时间】:2012-11-28 10:46:18
【问题描述】:

我可以成功地从我的客户端向我的服务器发送和绘制一个调整大小的 125 x 125 图像。唯一的问题是,那太小了。我希望能够发送更大的图像,但字节数组无法处理它,并且我得到一个 java 堆异常。目前我正在使用它来解释我的图像。有没有更有效的方法?

在客户端

screenShot = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                screenShot = resize(screenShot, 125, 125);

                ByteArrayOutputStream byteArrayO = new ByteArrayOutputStream();
                ImageIO.write(screenShot,"PNG",byteArrayO);
                byte [] byteArray = byteArrayO.toByteArray();
                out.writeLong(byteArray.length);
                out.write(byteArray);

上面调用的resize方法。

    public static BufferedImage resize(BufferedImage img, int newW, int newH) {  
    int w = img.getWidth();  
    int h = img.getHeight();  
    BufferedImage dimg = new BufferedImage(newW, newH, img.getType()); 
    Graphics2D g = dimg.createGraphics();  
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BILINEAR);  
    g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);  
    g.dispose();  
    return dimg;  
   } 

解释图像的服务器

in = new DataInputStream(Client.getInputStream());
            long nbrToRead = in.readLong();
            byte[] byteArray = new byte[(int) nbrToRead];
            int nbrRd = 0;
            int nbrLeftToRead = (int) nbrToRead;

            while (nbrLeftToRead > 0) {
                int rd = in.read(byteArray, nbrRd, nbrLeftToRead);
                if (rd < 0)
                    break;
                nbrRd += rd; // accumulate bytes read
                nbrLeftToRead -= rd;
            }
            ByteArrayInputStream byteArrayI = new ByteArrayInputStream(
                    byteArray);
            image = ImageIO.read(byteArrayI);

            if (image != null) {
                paint(f.getGraphics(), image);
            } else {
                System.out.println("null image.");
            }

正如您所见,代码量很大,而且很可能效率低下。我可以将图像的 1/10 发送 10 次以获得 with 和 height,而不是在这些部分上绘制,但我想知道是否有更简单的方法来做到这一点。

【问题讨论】:

  • 我觉得这和这个stackoverflow.com/questions/5113914/…有点相似
  • 这与我正在做的类似,但我的字节数组太大而无法处理任何内容> 125x125
  • 我试图避免阅读多个部分的屏幕
  • 是否需要将其作为字节数组发送?这就是造成您的尺寸限制的原因。为什么不通过对象流将其作为对象发送。
  • 我能做到吗?怎么会这样?以及如何将其转换回BufferedImage

标签: java image sockets


【解决方案1】:

您可能应该将数据传输视为网络上的流。您可以使用像 RMIIO 这样的第三方库。如果您可以使用 Web 服务进行数据传输,那么您可以查看消息传输优化机制 (MTOM),它可以让您以更有效的方式将数据作为流传输。更多详情请关注here

【讨论】:

  • 我稍后会看一下,但这似乎是我在简要阅读后需要的。谢谢!
【解决方案2】:

这对我有用

public class ImageClient {

  public static void main(String[] args) throws AWTException, IOException {

    BufferedImage screenShot = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
    Socket socket = new Socket("localhost",11111);
    MemoryCacheImageOutputStream byteArrayO = new MemoryCacheImageOutputStream(socket.getOutputStream());
    ImageIO.write(screenShot, "PNG", byteArrayO);
    byteArrayO.flush();
    socket.close();
  }

}


public class ImageServer {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ServerSocket ss = new ServerSocket(11111);
        try{
            Socket s = ss.accept();
            InputStream is = s.getInputStream();
            MemoryCacheImageInputStream ois = new MemoryCacheImageInputStream(is);
            ImageIO.read(ois);
            s.close();
        }finally{
            ss.close();
        }
   }
}

【讨论】:

    猜你喜欢
    • 2012-05-14
    • 1970-01-01
    • 2022-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多