【问题标题】:Sending image with byte array convertion, from java to c#使用字节数组转换发送图像,从java到c#
【发布时间】:2014-12-04 02:41:04
【问题描述】:

我正在尝试将我的 android 设备上的 .jpg 文件发送到我的服务器计算机。

为此,我通过 java android 应用程序将图片转换为字节数组,并将其作为参数发送到我的服务器计算机。我通过网络服务调用来做到这一点。

第一个函数被编辑:

public static byte[] ImageConvertion(){

    File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");
    byte[] data;

    try{
        FileInputStream input = new FileInputStream(inputFile);
        ByteArrayOutputStream output = new ByteArrayOutputStream ();

        byte[] buffer = new byte[65535];

        int l;

        while ((l = input.read(buffer)) > 0)
            output.write (buffer, 0, l);

        input.close();
        output.close();

        data = output.toByteArray();
        return data;


    } catch (IOException e) {
        System.err.println(e);
        data=null;
    }
    return data;

}

我的网络服务是用 ASP.NET (C#) 语言编写的,并且有一个函数将字节数组作为参数并将其转换回服务器计算机上的图像。

[WebMethod]
public void ByteArrayToPicture(byte[] imageData)
{
    using (var ms = new MemoryStream(imageData))
    {
        Image image = Image.FromStream(ms);
        image.Save(@"C:\newImage.jpg");
    }
}

但是,由于网络服务方面的原因,我无法做到这一点。我已经对其进行了调试,似乎问题出在 Image.FromStream() 函数上。

我在传递参数方面绝对没有任何问题。我认为无论是语言冲突还是将图像转换为字节,反之亦然,都可能导致问题。有没有人有任何想法或发现有问题?

我非常愿意提供任何帮助。

谢谢。

【问题讨论】:

  • 我不确定这是否是原因,但 java 的 byte 是有符号的(范围 -128 到 127),而 C# 的 byte 是无符号的(范围是 0 到 255)。如果您想让 C# 的字节匹配 java 的,请改用 sbyte(尽管这可能不是您的选择)。
  • @Pokechu22:两种语言的类型不同,但字节就是字节。在 Java 中表示(例如)-128 的相同位模式在 C# 中表示 128,但每个平台上的 JPEG 解码器将相同地解释该位模式。两种语言都不会对字节进行任何实际转换;唯一的区别是数学和文字在每种语言中的工作方式。

标签: c# android asp.net bytearray memorystream


【解决方案1】:

很抱歉我的问题不完整,但是我想给正在尝试做同样事情的人一些提示。

如果有人试图将图像发送到服务器并且双方有不同的平台,那么不要将图像转换为字节数组!

原因是,在我的情况下,在 Java 上转换为字节数组的图像与 C# 上的字节数组不同。因此,根据我的研究,不可能在服务器端收集图像。在 Java 上创建的字节数组在 C# 上不会有正确的格式。

因此,任何人都希望将数据从一种语言传输到另一种语言,因此请使用 Base64 编码。在一侧将图像转换为 Base64 字符串,并将其作为字符串发送到另一种语言。由于 Base64 格式在每种语言上都是相同的,因此重现它不会有任何问题。

我用以下代码出售了问题:

Bitmap ourbitmap = BitmapFactory.decodeStream(imageStream, null, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
ourbitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);   
byte[] b = baos.toByteArray(); 
test = Base64.encodeToString(b, Base64.DEFAULT); 

这是我获取图像并将其转换为 Java android 应用程序上的 Base64 字符串的代码,

byte[] imageBytes = Convert.FromBase64String(Base64ImageData); 
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);

ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
image.Save(@"D:\tmpImage.jpg");

上面的代码采用 Base64 类型的字符串并转换回图像。这是用 C# 编写的。

【讨论】:

  • 不错的答案!但我有一个问题:你是如何在 android 端调用 web 服务的?作为链接,例如:http://host/service/upload/base64_string_goes_here?因为,我也面临这个问题,我在 WCF 中编写了我的 web 服务......我的主要问题是 URL(我在 android 应用程序中调用它)。当我将图像编码为 base64 时,URL 的长度大于 100.000。因此,HTTP 标准 (it allows max 2000 chars in URL) 中不允许此长度。那么,你现在能帮帮我吗?
  • @MirjalalTalishinski 我的 Web 服务类型是 IIS .asmx Web 服务。我能够通过在android端使用soap-envelope方法来传递参数(int、boolean和string)。由于我对 WCF Web 服务没有任何经验,因此无法提供任何建议。不幸的是,通过快速谷歌我看到,Web 端点通过 XML 或 JSON 发送数据,没有 SOAP 信封因此,如果我没记错的话,你不能在你的情况下使用soap方法......
  • 感谢您的回复。好的,我明白了。但如果你能请,看看这个问题,告诉我我错在哪里......(我认为 WCF 和 ASMX 项目有点相同:))stackoverflow.com/q/31219056
【解决方案2】:

这样一个不完整的代码示例和这样一个模糊的问题描述,很难确定问题是什么。

但是,在查看您发布的代码时,我发现了一个错误,如果这确实是您正在使用的代码,那么该错误将非常重要。在您的 Java methodConvertion() 方法中,您有以下语句:

data = output.toByteArray();

问题在于,所做的只是创建一个新的byte[] 对象并将引用分配给名为data 的本地 变量。该对象永远不会离开方法。

大概你有一些其他代码,在调用methodConvertion() 之后,发送你传递给该方法的参数引用的byte[] 对象。但该对象将与您调用该方法之前的任何内容相同。

您应该改为更改您的 Java 代码,使其看起来像这样:

public static byte[] methodConvertion(){
    File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");

    try{
        FileInputStream input = new FileInputStream(inputFile);
        ByteArrayOutputStream output = new ByteArrayOutputStream ();

        byte [] buffer = new byte [65536];
        int l;

        while ((l = input.read(buffer)) > 0)
            output.write (buffer, 0, l);

        input.close();
        output.close();

        return output.toByteArray();

    } catch (IOException e) {
        System.err.println(e);
        return null;
    }
}

然后在调用者中,你应该检查返回值,只有当值不是null时才继续,否则会报告错误。

如果这不能解决您的问题,您应该编辑问题,使其具有a better code example,这样您就可以更具体地了解问题所在。当您运行代码时会发生什么,这与您的预期有何不同?请务必明确说明任何错误消息,准确引用它们,并包括异常的任何堆栈跟踪。

【讨论】:

  • 感谢您的回复。我想让我的问题更简单,而不是写一篇文章式的问题。但似乎这个问题可能有点模糊。您提到的错误帮助我摆脱了崩溃错误。但我还是没有得到任何结果。
  • 好吧,既然你的问题一开始就没有提到崩溃,我想这就是进步。抱歉,您认为这不是问题的答案。有关如何使您的问题更容易回答的建议,请参阅我的最后一段。
猜你喜欢
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
相关资源
最近更新 更多