在Apple设备上解码base64文本字符串时为什么会看到裁剪的图像?

问题描述 投票:1回答:1

我有一个iOS应用,该应用从API获取作为base64编码字符串的图像。 (我知道这也许不是最好的解决方案,但这不是问题)。

当我解码此字符串以使用以下代码创建UIImage时:

// If don't don't append "=" I'll get nil data in the next line: (string.count % 4 == 0) is required
    let stringWithEquals:String = getMyString() + "=" 
    let data = Data.init(base64Encoded: stringWithEquals, options: .ignoreUnknownCharacters)!
    self.myPicture.image = UIImage(data: data )

返回的图像被裁剪(我添加红色背景只是出于开发目的):

enter image description here

如您所见,我收到一条错误消息,说“无法将UIImage转换为PNG”


因此,我开始认为代码中可能存在错误。也许我得到的字符串不完整,或者解码中缺少一些步骤。因此,我问后端人员,他确认我该字符串正确。我还与同事一起检查了谁使用了Android版本,并且相同的字符串在他的应用程序中也可以正常工作。

所以我在在线解码器中测试了字符串,并使用Safari

Versión13.0.5(15608.5.11)建立了相同的cropped结果,但使用Firefox]创建了full图像

enter image description hereWTF

我在多个网络解码器中以相同的结果对其进行了测试:

enter image description here这是从Firefox以png和jpg格式下载的图像

我一直在尝试在Google和一些论坛中找到解决方案,其中包括很多StackOverflow问题,但与此无关。

请注意以下几点:

  • 返回的解码数据不是零。我在字符串的末尾添加了“ =”字符,以确保字符串长度%4 == 0。我发现了很多有关该问题的问题,我可以解码图像,但裁剪。
  • 我100%确信字符串是完整的,我已经与后端和android同事进行了检查。
  • 这似乎是与Apple环境有关的问题,我的iOS应用程序中的图像都无法在Safari中看到,但是我可以在Mac计算机上运行的Firefox中看到它。同样,这不仅发生在我的计算机上。其他一些同事在他们的iPhone中进行了测试,结果相同。

  • base64字符串非常长

(我将在下面粘贴)。因此,我尝试解码字符串的一半,以确保问题与大小无关,并且发现了一些古玩东西。如果我只解码一半的字符串,我的结果也会被裁剪:
    let stringWithEquals:String = getMyString().prefix(getMyString().count/2) + "="

enter image description here

我不知道这种近似是否正确,但是我尝试过。


我试图使用Objective-C

函数找到一个解决方案,但结果是相同的:
-(NSData *)base64DataFromString: (NSString *)string{
    unsigned long ixtext, lentext;
    unsigned char ch, inbuf[4], outbuf[3];
    short i, ixinbuf;
    Boolean flignore, flendtext = false;
    const unsigned char *tempcstring;
    NSMutableData *theData;

    if (string == nil){
        return [NSData data];
    }

    ixtext = 0;

    tempcstring = (const unsigned char *)[string UTF8String];

    lentext = [string length];

    theData = [NSMutableData dataWithCapacity: lentext];

    ixinbuf = 0;

    while (true){
        if (ixtext >= lentext){
            break;
        }
        ch = tempcstring [ixtext++];

        flignore = false;

        if ((ch >= 'A') && (ch <= 'Z')){
            ch = ch - 'A';
        }else if ((ch >= 'a') && (ch <= 'z')){
            ch = ch - 'a' + 26;
        }else if ((ch >= '0') && (ch <= '9')){
            ch = ch - '0' + 52;
        }else if (ch == '+'){
            ch = 62;
        }else if (ch == '='){
            flendtext = true;
        }else if (ch == '/'){
            ch = 63;
        }else{
            flignore = true;
        }

        if (!flignore){
            short ctcharsinbuf = 3;
            Boolean flbreak = false;

            if (flendtext){
                if (ixinbuf == 0){
                    break;
                }
                if ((ixinbuf == 1) || (ixinbuf == 2)){
                    ctcharsinbuf = 1;
                }else{
                    ctcharsinbuf = 2;
                }
                ixinbuf = 3;

                flbreak = true;
            }

            inbuf [ixinbuf++] = ch;

            if (ixinbuf == 4){
                ixinbuf = 0;

                outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
                outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
                outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);

                for (i = 0; i < ctcharsinbuf; i++){
                    [theData appendBytes: &outbuf[i] length: 1];
                }
            }

            if (flbreak){
                break;
            }
        }
    }
    return theData;
}

因此,我现在完全迷失了。为什么会这样?

这里是damm base64字符串

THE DAMM STRING AT GITHUB

我有一个iOS应用,该应用从API获取图像作为base64编码的字符串。 (我知道这也许不是最好的解决方案,但这不是问题)。当我解码此字符串以创建UIImage时...

ios objective-c swift macos safari
1个回答
0
投票

事实上,您必须“ 追加” =“ ...,以便可以被4整除]]”是一个大提示。这意味着您的字符串格式不正确。

© www.soinside.com 2019 - 2024. All rights reserved.