㈠ android webkit图片解码流程是什么呢在看源码的时候注意到再\external\webkit\WebCore\platform\image-d
不是,android中对图片解码是放在external里面有个skia的第三方郑罩粗库。里面封装了它对jpg,png ,gif,bmp等图片解码的支持。这些图片解码闷旁时会用到external里面的libjpg ,libgif,libpng等解码库。如果你需要支持tiff格式,也可以在里喊镇面添加libtif 库。同时修改skia里面的部分代码。如若需要具体方法,网络hi我
㈡ Android编码解码及其原理
本文摘抄至: chendong_ 的博客
本文用到ASCII表,Base64对照表请自行网络。
概念:编码解码就是使用特定的算法轿帆,将数据进行处理,形成数据的另外一种表现形式,编码后的数据可以使用解码算法还原出原始数据。
洞帆拆 Base64算法可以将任意的字节数组数据通过算法生成只有(英文大小写,数字,+,/)共64种字符的字符串数据;相当于将任意内容转换为可见字符串表示。
也就是将不可见的数据转换为ASCII码数据,便于在Json和Xml中传递。
字符串String str = "0Aa";首先,原先每个字符是2个字节16bit,对于英文来说前8个bit是0,也就是只有8个bit,现在是3个字符,3*8=24个bit需要显示。
现在拼凑成是这样的二进制串( 001100 000100 000101 100001),将其转化为Base64可以显示的模式,需要每次取6位作为一个Base64字符,前两位补0
这个例子已经很清晰的解释了Base64的编码过程,网上有人自己实现了Base64编码的类,Android源码也不难,这是编码字符串看起来还是比较清晰的,我们也可以更本质一点
byte[] bs = new byte[]{1,10,20};这是一个byte数组,复习一下,1个byte是8个bit,可以表示的范围 0-127之间,我们在调用Base64的函数时,本质也是在操作字节数组,同样的原理
Hex就是16进制,本质上是将字节数组转化为16进制,然后用字符串的形式表现出来,我们知道16进制的取值范围就是在0-f之间,这样就可以将无法显示的字节数组数据显示出来。
原理方面比起Base64就简单很多了,一个8bit的数据,也就是(xxxx xxxx),每4个bit可以转化为一个16进制表示,也就是8个bit会转化为(00-ff)之间的16进制数字。
简单说一下,&运算,两者都为1结果才是1,b>>4&0xf取出高四位,b&0x0f取出低四位,举个例子:
1、字节是 b = 1010 1111
2、b>>4 b = 00001010
3、b>>4&0x0f 也就是 00001010&00001111 —-> 1010高四位取出来了,取得低四位原理一样。后面的操作就是根据数据的大小转换一下格式,因为拿到的数据是十进制的那么范围会在0-15之间,需要转换为16进制的0-f.
相当于编纳枣码的逆运算,根据字符串每次取两位,转换成int,在进行移位将其拼成一个字节,怎么拼的?v = ((ih&0x0f)<<4)|(il&0x0f);
这一句,假设我们获得的字符串最后转化结果是10和5,也就是1010,0101。10<<4,结果是10100000,然后10100000 | 0101,|运算只要有1则为1,结果是10100101就完成了拼接工作。
Base64和Hex是比较常见的编码方式,对比一下,Base64每3个字节转化为4个字节,每个字节浪费2bit,Hex编码,每个字节转化为两个字节,每个字节浪费4bit,所以说Base64更加节省空间,而且用起来简单得多。
㈢ Android原生编解码接口 MediaCodec 之——完全解析
MediaCodec 是Android 4.1(api 16)版本引入的编解码接口, Developer 官网 上描述的已经很清楚了。可以配合 中文翻译 一起看。理解更深刻。
MediaCodec的工作流程:
从上图培册可以看出 MediaCodec 架构上采用了2个缓冲区队列,异步处理数据,并且使用了一组输入输出缓存。
你请求或接收到一个空的输入缓存(input buffer),向其中填充满数据并将它传递给编解码器处理。编解码器处理完这些数据并将处理结果输出至一个空的输出缓存(output buffer)中。最终,你请求或接收到一个填充了结果数据的输出缓存(output buffer),使用完其中的数据,并将其释放给编解码器再次使用。
具体工作如下:
MediaCodec的基本调用流程是:
1.初始化MediaCodec,方法有两种,分别是通过名称和类型来创建,对应的方法为:
2.配置编码器,设置各种编码器参数(MediaFormat),这个类包含了比特率、帧率、关键帧间隔时间等。然后再调用 mMediaCodec .configure,对于 API 19 以上的系统,我们可以选择 Surface 输入:mMediaCodec .createInputSurface,
3.打开编码器,获取输入输出缓冲区
获取输入输出缓冲区在api19 上是以上方式获取,api21以后 可以使用直接获取ByteBuffer
4.输入数据,有2种方式,一种是普通输入,一种是Surface 输入
普通输入又可区分为两种情况,一种是配合MediaExtractor ,一种是取原数据;
返回一个填充了有效数据的input buffer的索引,如果没有可用的buffer则返回-1,参数为超时时间(TIMES_OUT),单位是微秒,当timeoutUs==0时,该方法立即返回;当timeoutUs<0时,无限期地等待一个可用的input buffer,当timeoutUs>0时,
等待时间为传入的微秒值。
上面输入缓存的index,通过getInputBuffers()得到的是输入缓存数组,通过index和输入缓存数组可以得到当前请求的输入缓存,在使用之前要clear一下,避免之前的缓存数据影响当前数据,接着就是把数据添加到输入缓存中,并调用queueInputBuffer(...)把缓存数据入队;
5.输出数据
通常编码传输时每个关键帧头部都需要带上编码配置数据(PPS,SPS),但 MediaCodec 会在首次输出时专门输出编码配置数据,后面的关键帧里是不携带这些数据的,所以需要我们手动做一个拼接;
6.使用完MediaCodec后释放资源
要告知编码器我们要结束编码,Surface 输入的话调用 mMediaCodec .signalEndOfInputStream,普通输入则可以为在 queueInputBuffer 时指定 MediaCodec.BUFFER_FLAG_END_OF_STREAM 这个 flag;告知编码器后我们就可以等到编码器输出的 buffer 带着 MediaCodec.BUFFER_FLAG_END_OF_STREAM 这个 flag 了,等到之后我们调用 mMediaCodec .release 销毁编码器
流控就是流量控制。 为什么要控制,就是为了在一定的限制条件下,收益最大化!
涉及到了 TCP 和视频编码:
对 TCP 来说就是控制单位时间内发送数据包的数据量,对编码来说就是控制单位时间内输出数据的数据量。
TCP 的限制条件是网络带宽,流控就是在避免造成或者加剧网络拥塞的前提下,尽可配汪宏能利用网络带宽。带宽够、网络好,我们就加快速度发送数据包,出现了延迟增大、丢包之后,就放慢发包的速度(因为继续高速发包,可能会加剧网络拥塞,反而发得更慢)。
视频编码的限制条件最初是解码器的能力,码率太高就会无法解码,后来随着 codec 的发展,解码能力不再是陵键瓶颈,限制条件变成了传输带宽/文件大小,我们希望在控制数据量的前提下,画面质量尽可能高。
一般编码器都可以设置一个目标码率,但编码器的实际输出码率不会完全符合设置,因为在编码过程中实际可以控制的并不是最终输出的码率,而是编码过程中的一个量化参数(Quantization Parameter,QP),它和码率并没有固定的关系,而是取决于图像内容。 这一点不在这里展开,感兴趣的朋友可以阅读视频压缩编码和音频压缩编码的基本原理。
无论是要发送的 TCP 数据包,还是要编码的图像,都可能出现“尖峰”,也就是短时间内出现较大的数据量。TCP 面对尖峰,可以选择不为所动(尤其是网络已经拥塞的时候),这没有太大的问题,但如果视频编码也对尖峰不为所动,那图像质量就会大打折扣了。如果有几帧数据量特别大,但仍要把码率控制在原来的水平,那势必要损失更多的信息,因此图像失真就会更严重。 这种情况通常的表现是画面出现很多小方块,看上去像是打了马赛克一样,导致画面的局部或者整体看不清楚的情况
配置时指定目标码率和码率控制模式:
码率控制模式有三种:
码率控制模式在 MediaCodecInfo.EncoderCapabilities 类中定义了三种,在 framework 层有另一套名字和它们的值一一对应:
动态调整目标码率:
Android 流控策略选择
下面展示使用MediaExtractor获取数据后,用MediaMuxer重新写成一个MP4文件的简单栗子
㈣ 在Android系统中如何调用系统自带的视频解码器
对需要用FF解码的视频类型去掉内颂卖悉配陵部解码勾选
2.在外部解码器中对所选视频选择FF解码器即野乎可
㈤ Javaweb返回给Android客户端json中文字符乱码
JavaWeb的各种中文乱码终极解决方法:
一、Servlet输出乱码
1. 用servlet.getOutStream字节流输出中文,假设要输出的是String str ="测试中文"。
1.1 若是本地服务器与本地客户端这种就不用说了,直接可以out.write(str.getBytes())可以输出没有问题。因为服务器中用str.getBytes()是采用默认本地的编码,比如GBK。而浏览器也解析时也用本地默认编码,两者是统一的,所以没有问题。
1.1 若服务器输出时用了, out.write(str.getBytes("utf-8"))。而本地默认编码是GBK时(比例在中国),那么用浏览器打开时就会乱码。因为服务器发送过来的是utf-8的1010数据,而客户端浏览器用了gbk来解码,两者编码不统一,肯定是乱码。当然,你也可以自己将客户端浏览器的编码手工调用下(IE菜单是:查询View->编码encoding->utf-8),但是这种操作很烂,最好由服务器输出响应头告诉,浏览器用哪种编码来解码。所以要在服务器的servlet中,增加response.setHeader("content-type","text/html;charset=utf-8"),当然也可直接用简单的response.setContentType("text/hmtl;charset=utf-8")。两种的操作是一样一样的。
2. 用servlet.getWirter字符流输出中文,假设要输出的扰旦是String str ="测试中文乱码"。
2.1 若写成out.print(str)输出时,客户端浏览器显示的将全是多个?????的字符,代表在编码表中肯定就找不到相应的字符来显示。原因是:servlet.getWriter()得到的字符输出流,默认对字符的输出是采用ISO-8859-1,而ISO-8859-1肯定是不支持中文的。所以肯定要首先要做的第一件事:是要将服务器对象输出字符能支持中文的。其次服务器向客户端写回的响应头要告诉客户端是用了哪种编码表进行编码的。而实现这两个需求,只需要response.setContentType("text/hmtl;charset=utf-8")。斗李族就搞定了。特别注意:response.setContentType("text/html;charset=utf-8")要放在PrintOut out = response.getWriter()代码的前面,否则只是有告诉客户端用什么码表编码的功能,而服务器端还是用ISO-8859-1编码了。再特别提示下:在同一Servlet中的doGet或doPost方法中,不能既用response.getOutputStream又用response.getWriter,因为这两种response的响应输出字节流与字符流是冲突的,只能用其一。
二、Servlet文件下载,中文乱码情况。
关键是下载时响应头 content-disposition中attachment;filename=文件名。这个文件名filename不能是含有中文字符串的,要用URLEncoding编码进行编码,才能进行进行http的传输。
三、Servlet的response增加addCookie,cookie中value的中文码问题解决方法。若想将cookie中存放中文的值,必须用Base64编码后,发给客户浏览器端进入存储。而下次客户端浏览访问是带回来的cookie中的值,是经过Base64编码的,所以需要用Base64解码即可。 Base64编码主要是解决将特殊字符进行重新编码,编码成a-b、A-B、0-9、+与/,字符52,10个数字与一个+,一个/ 共64个字符。它的原理是将原来3个字节的内容编码成4个字节。主要是取字节的6位后,在前面补00组成一个新的字节。所以这样原来的3个字节共24,被编码成4个字节32位了。
四、获取请求参数乱码
GET方式的乱码:
如<a href=”/demo5/servlet/RD2?name=中国”>CN</a>,空弊直接用request.getParameter得到的字符串strCN将会乱码,这也是因为GET方式是用http的url传过来的默认用iso-8859-1编码的,所以首先得到的strCn要再用iso-8859-1编码得到原文后,再进行用utf-8(看具体页面的charset是什么utf-8或gbk)进行解码即可。new String(strCn.getBytes(“ISO-8859-1”),“UTF-8”);
㈥ 如何解决Android WebView出现的乱码问题
1、webView.loadUrl();
直接显示网页内容(单独显示网络图片),一般不会出现乱码。
2、webView.loadData(data, "text/html", "UTF-8");
loadData主要被设计用来装载URI格式的数据,它不能通过网络来加载内容。网上流传的webview加载中文出现乱码,多数是使用此方法。使用过程中主要有两个问题:
(1)loadData不能加载图片内容,如果想加载图片内容或者获得更强大的Web支持建议使用更强大的loadDataWithBaseURL.
(2) 许多实用loadData方法的朋友都遇到显示乱码的问题,那是因为编码器设置错误导致的。我们知道String类型的数销镇据主要是unicode编码,而WebView一般为了节省资源使用的是UTF-8编码,所以我们在loadData的时候要告诉方法怎样转码。即要告诉它要将unicode编码的内容转成UTF-8编码的内容。有些朋友虽然在loadData的时候设置了编码方式,但是还是显示乱码,这是因亏消粗为还需要为WebView的text编码指定编码方式。举例如下:
WebView wv = (WebView)findViewById(R.id.webview) ;
wv.getSettings().setDefaultTextEncodingName(“UTF -8”) ;
wv.loadData(content, “text/html”桥碰, “UTF-8”) ;
注意为gb2312或gbk
(3).网页说明编码格式
以上两种方法是网上给的比较好的方法,但是我都试了下都没有解决我的乱码问题。 原来我是用LoadData方法来解析html的,但是据说这是官方的一个BUG,不能用来解析中文。所以绕其道而行之,采用loadDataWithBaseURL的方法,其中codeingType设置为utf-8就OK了。3、loadDataWithBaseURL如果单纯显示文字的话可以写webView.loadDataWithBaseURL(null, string, "text/html", "utf-8", null);
如果要显示图片可以写webView.loadDataWithBaseURL(baseUrl, string, "text/html", "utf-8", null);
其中baseUrl为你存储照片的路径,比如: