ADB截图后返回的内存流,需要经过格式化才能转成图片,求解答

张天星 2019-06-27 03:21:39
网络上找的代码,使用上正常,但是看不懂,求解。
adb命令,执行命令后返回了一段内存流MemoryStream
内存流转文字什么的都正常。
但是如果想要转成图片(也就是从手机上进行截图),那么这个内存流就不能用了,必须经过转换。
下面是转换的代码,求问:Fix0d0d0a这个方法做了什么。

public Bitmap GetBitmap()
{
byte[] bytes = Fix0d0d0a(OutStream.ToArray());
using (MemoryStream pngStream = new MemoryStream(bytes))
{
return new Bitmap(pngStream);
}
}
private byte[] Fix0d0d0a(byte[] bytes)
{
long length = bytes.Length;
byte[] bytesfix = new byte[length];

int idx = 0;
int count = 0;
int idxFirst0D = 0;
int idxFirst0A = 0;
bool is0D = false;
for (int i = 0; i < length; i++)
{
byte b = bytes[i];
if (b == 0x0d && idxFirst0D == 0)
{
idxFirst0D = i;
is0D = true;
}
if (b == 0x0a && idxFirst0A == 0)
{
idxFirst0A = i;
}
if (i > 2 && b == 0x0a && is0D)
{
count++;
idx = idx - (idxFirst0A - idxFirst0D - 1);
bytesfix[idx] = b;
idx++;
}
else
{
bytesfix[idx] = b;
idx++;
}
if (b == 0x0d)
is0D = true;
else
is0D = false;
}
byte[] bytesfinal = new byte[length - count * (idxFirst0A - idxFirst0D - 1)];
Buffer.BlockCopy(bytesfix, 0, bytesfinal, 0, bytesfinal.Length);
return bytesfinal;
}
...全文
560 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
小张。。 2019-06-27
  • 打赏
  • 举报
回复
总算将疑虑搞清楚了。 结贴了。 准备把答案发上来了, 却发现。。。连续回复3次,回复不了了。。。 无奈注册个小号上来回复: 最后结贴,大概说下两个疑问的答案: 0d0d0a是\r\r\n 最后要转图片,就要替换成\n 至于idx = idx - (idxFirst0A - idxFirst0D - 1),是因为有的手机返回的是\r\n,有的手机返回的是\r\r\n,但是操作图片的时候,都需要转成\n 此外,source.Skip(i).Take(3).SequenceEqual(bba)效率很低。 一个80W字节(800KB)的图片重新编码,要用5分钟时间,但是不知道Skip Take SequenceEqual 这三个方法哪个是速度慢的罪魁祸首。 直接用source[i] == 0x0d && source[i + 1] == 0x0d && source[i + 2] == 0x0a的效率就强太多太多了。1秒钟搞定。
张天星 2019-06-27
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
话说,那个代码看着郁闷,我修整一下
    private static byte[] bba = new byte[] {0x0b, 0x0b, 0x0c};
        static void Main(string[] args)
        {
            byte[] source = new byte[] { 0x0b, 0x0b, 0x0c };

            var res = fix(source).ToList();
        }

      static   IEnumerable<byte> fix(byte[] source)
        {
            for (var i = 0; i < source.Length; i++)
            {
                if (!source.Skip(i).Take(3).SequenceEqual(bba))
                    yield return source[i];
            }
        }
    }
多谢,没用过yield,现在发现很好用。 source.Skip(i).Take(3).SequenceEqual(bba)这一段的效率非常低,我换掉了。 0d0d0a重新编码成0a,所以下面找到匹配的0d0d0a之后,i+1,移动到0a的位置。

private IEnumerable<byte> fix(byte[] source)
        {
            for (var i = 0; i < source.Length; i++)
            {
                if (source[i] == 0x0d && source[i + 1] == 0x0d && source[i + 2] == 0x0a)
                {
                    i += 1;
                }
                else
                {
                    yield return source[i];
                }
            }
        }
此外,还是有疑惑, 1、为啥安卓将0a编码成0d0d0a,有什么特别意义么。 2、代码中,idx = idx - (idxFirst0A - idxFirst0D - 1),为啥不能直接idx-2,仅仅是原作者随便写的,还是因为这中间的距离会有什么变化?
张天星 2019-06-27
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
话说,那个代码看着郁闷,我修整一下
    private static byte[] bba = new byte[] {0x0b, 0x0b, 0x0c};
        static void Main(string[] args)
        {
            byte[] source = new byte[] { 0x0b, 0x0b, 0x0c };

            var res = fix(source).ToList();
        }

      static   IEnumerable<byte> fix(byte[] source)
        {
            for (var i = 0; i < source.Length; i++)
            {
                if (!source.Skip(i).Take(3).SequenceEqual(bba))
                    yield return source[i];
            }
        }
    }
速度非常慢,一个80W字节的图片,用了五分多种的时间,不知道为什么这么慢。 而且结果是不能用的,我想了想,yield return source[i]这里,i可能需要+2,我再试试
张天星 2019-06-27
  • 打赏
  • 举报
回复
引用 1 楼 wanghui0380 的回复:
原因“图片经过了安卓的编码处理,把0d0a修改成了0d0d0a” 所以这个代码就是从新编码,把0d0d0a重新编码成0d0a
我看了下,但看目前逻辑,是将0d0d0a重新编码成0a,每一次替换,都会减少2个字节。 主要疑惑有2个: 1、为啥安卓将0a编码成0d0d0a,有什么特别意义么。 2、代码中,idx = idx - (idxFirst0A - idxFirst0D - 1); 为啥要0a-0d,难道他们中间的距离还会发生变化么? 就是前移两个位置,idx = idx -2,直接这样写可以么。
wanghui0380 2019-06-27
  • 打赏
  • 举报
回复
话说,那个代码看着郁闷,我修整一下
    private static byte[] bba = new byte[] {0x0b, 0x0b, 0x0c};
        static void Main(string[] args)
        {
            byte[] source = new byte[] { 0x0b, 0x0b, 0x0c };

            var res = fix(source).ToList();
        }

      static   IEnumerable<byte> fix(byte[] source)
        {
            for (var i = 0; i < source.Length; i++)
            {
                if (!source.Skip(i).Take(3).SequenceEqual(bba))
                    yield return source[i];
            }
        }
    }
wanghui0380 2019-06-27
  • 打赏
  • 举报
回复
原因“图片经过了安卓的编码处理,把0d0a修改成了0d0d0a” 所以这个代码就是从新编码,把0d0d0a重新编码成0d0a

110,569

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧