【问题标题】:uploaded images from iOS and android are different从 iOS 和 android 上传的图像是不同的
【发布时间】:2025-12-30 14:15:12
【问题描述】:

我有一个带有 iOS 版本和 android 版本的应用程序。该应用使用分段上传将图像(在本例中为 jpeg)从图库或相机发送到服务器。

图像的大小、分辨率和文件大小一开始是相同的,当我运行 imagemagick 比较时,它们是相同的。

当它们到达服务器时,它们看起来与肉眼相同,具有相同的像素数和尺寸,均为 320 x 483,分辨率为 72 像素。但是,尽管加载每个都没有指定压缩,但它们具有不同的文件大小。当我运行 imagemagick 比较时,它们明显不同。

这些是原始图像:

Image on iPhone

Image on Android

这些是上传时的图片:

Image uploaded from iPhone

Image uploaded from Android

imagemagick compare image

IOS 代码(使用 AFnetworking)

UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
NSData *imageData = UIImageJPEGRepresentation(img, 1.0);
UIGraphicsEndImageContext(); ...
[requestSerializer setValue:@"multipart/form-data" forHTTPHeaderField:@"content-type"];

NSMutableURLRequest *request = [requestSerializer multipartFormRequestWithMethod:@"POST" URLString: ServerPath
                    parameters:sendDictionary constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

    [formData appendPartWithFileData: imageData name:@"file" fileName:@"temp.jpeg" mimeType:@"image/jpeg"];

} error:nil];

Android 代码(使用 loopj 进行异步请求)

    RequestParams params = new RequestParams(); 

    params = new RequestParams();

    //use bytearray
    BitmapFactory.Options BMoptions = new BitmapFactory.Options();
    BMoptions.inSampleSize = 1; // Example, there are also ways to calculate an optimal value.

    InputStream in;
    try {
        in = getContentResolver().openInputStream(Uri.fromFile(new File(Globals.getImagePath())));

        Bitmap bitmap = BitmapFactory.decodeStream(in, null, BMoptions);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap = scaleToActualAspectRatio2(bitmap);

        //
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        bitmapdata = baos.toByteArray();

        params.put("file", new ByteArrayInputStream(bitmapdata), "androidMobile.jpg");

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }           

我认为是像素强度造成了差异。

有人可以解释为什么图像到达不同吗?我是否必须先将 Android 图像保存到文件中并将其作为文件上传?

【问题讨论】:

  • 您可以随时比较字节以查看发生了什么变化。
  • iOS 图像的大小调整和上传似乎添加了白色边框。这可能是由于在调整大小期间重新采样,然后舍入或截断到最接近的整个像素。根据高度调整大小时宽度的最后一个像素可能不是完整像素。例如。 (483/640)*423=319.2328125 但是图像被填充到 320 的宽度。319.2 可能被你的 iOS 代码用白色填充到 320;而它是使用 Android 代码中最后一列的图像像素数据进行插值或扩展的。也许有一个虚拟像素设置可以缓解 iOS 中的这种情况。
  • 我能理解你所说的边界,但似乎有一个更全球性的变化。您认为这是由于填充引起的像素位置的变化吗?

标签: android ios image multipart


【解决方案1】:

在 Android 下,您不会上传 jpeg 文件。

相反,您将 jpeg 文件转换为位图并将该位图压缩为最终要上传的一些字节。

难怪你最终会得到不同的字节。

取消位图。直接上传jpg文件的字节就好了。

 params.put("file", new ByteArrayInputStream(bitmapdata), "androidMobile.jpg");

改成

 params.put("file", in, "androidMobile.jpg");

直接删除位图代码,因为输入流只能读取一次。

【讨论】:

  • 是的,这似乎是一个可能的答案,我正计划下一步尝试。如果我从相机上传图像,这意味着我必须先将其保存到文件系统还是四处寻找假定的位置?
  • 如果您以正确的方式使用相机意图,相机应用程序会将图像保存到您指定的文件中,然后您就已经知道它是哪个文件了。