干货分享,图片模糊算法,解析xml绘制图片

前端之家收集整理的这篇文章主要介绍了干货分享,图片模糊算法,解析xml绘制图片前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。





项目需求:有一个xml文件,记录了一张图片每个元素的位置,大小,样式信息。

通过XmlResourceParser解析xml文件,得到每个元素的属性

然后使用Paint绘制元素到Canvas上,得到一张Bitmap位图

将位图模糊处理,处理算法的原理(取图片上每个像素点周围的8个点平均值)



模糊算法:


  1. package com.metek.blur;
  2.  
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5.  
  6. public class BlurUtils {
  7. /**
  8. * Android api 17实现的虚化
  9. * 某些机型上可能会Crash
  10. *
  11. * @param context
  12. * @param sentBitmap
  13. * @param radius 大于1小于等于25
  14. * @return
  15. */
  16. public static Bitmap fastblur(Context context,Bitmap sentBitmap,int radius) {
  17. if (sentBitmap == null) {
  18. return null;
  19. }
  20. // if (Build.VERSION.SDK_INT > 16) {
  21. // Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(),true);
  22. //
  23. // final RenderScript rs = RenderScript.create(context);
  24. // final Allocation input = Allocation.createFromBitmap(rs,// sentBitmap,Allocation.MipmapControl.MIPMAP_NONE,// Allocation.USAGE_SCRIPT);
  25. // final Allocation output = Allocation.createTyped(rs,// input.getType());
  26. // final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs,// Element.U8_4(rs));
  27. // script.setRadius(radius /* e.g. 3.f */);
  28. // script.setInput(input);
  29. // script.forEach(output);
  30. // output.copyTo(bitmap);
  31. // return bitmap;
  32. // }
  33. return stackblur(sentBitmap,radius);
  34. }
  35. /**
  36. * 纯Java实现的虚化,适用老版本api,外部只需调fastblur,会自动判断
  37. *
  38. * @param sentBitmap
  39. * @param radius
  40. * @return
  41. */
  42. private static Bitmap stackblur(Bitmap sentBitmap,int radius) {
  43. Bitmap bitmap = null;
  44. try {
  45. bitmap = sentBitmap.copy(sentBitmap.getConfig(),true);
  46. } catch (OutOfMemoryError e) {
  47. e.printStackTrace();
  48. return sentBitmap;
  49. }
  50. if (radius < 1) {
  51. return (null);
  52. }
  53. int w = bitmap.getWidth();
  54. int h = bitmap.getHeight();
  55. int[] pix = new int[w * h];
  56. bitmap.getPixels(pix,w,h);
  57. int wm = w - 1;
  58. int hm = h - 1;
  59. int wh = w * h;
  60. int div = radius + radius + 1;
  61. int r[] = new int[wh];
  62. int g[] = new int[wh];
  63. int b[] = new int[wh];
  64. int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
  65. int vmin[] = new int[Math.max(w,h)];
  66. int divsum = (div + 1) >> 1;
  67. divsum *= divsum;
  68. int dv[] = new int[256 * divsum];
  69. for (i = 0; i < 256 * divsum; i++) {
  70. dv[i] = (i / divsum);
  71. }
  72. yw = yi = 0;
  73. int[][] stack = new int[div][3];
  74. int stackpointer;
  75. int stackstart;
  76. int[] sir;
  77. int rbs;
  78. int r1 = radius + 1;
  79. int routsum,goutsum,boutsum;
  80. int rinsum,ginsum,binsum;
  81. for (y = 0; y < h; y++) {
  82. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  83. for (i = -radius; i <= radius; i++) {
  84. p = pix[yi + Math.min(wm,Math.max(i,0))];
  85. sir = stack[i + radius];
  86. sir[0] = (p & 0xff0000) >> 16;
  87. sir[1] = (p & 0x00ff00) >> 8;
  88. sir[2] = (p & 0x0000ff);
  89. rbs = r1 - Math.abs(i);
  90. rsum += sir[0] * rbs;
  91. gsum += sir[1] * rbs;
  92. bsum += sir[2] * rbs;
  93. if (i > 0) {
  94. rinsum += sir[0];
  95. ginsum += sir[1];
  96. binsum += sir[2];
  97. } else {
  98. routsum += sir[0];
  99. goutsum += sir[1];
  100. boutsum += sir[2];
  101. }
  102. }
  103. stackpointer = radius;
  104. for (x = 0; x < w; x++) {
  105. r[yi] = dv[rsum];
  106. g[yi] = dv[gsum];
  107. b[yi] = dv[bsum];
  108. rsum -= routsum;
  109. gsum -= goutsum;
  110. bsum -= boutsum;
  111. stackstart = stackpointer - radius + div;
  112. sir = stack[stackstart % div];
  113. routsum -= sir[0];
  114. goutsum -= sir[1];
  115. boutsum -= sir[2];
  116. if (y == 0) {
  117. vmin[x] = Math.min(x + radius + 1,wm);
  118. }
  119. p = pix[yw + vmin[x]];
  120. sir[0] = (p & 0xff0000) >> 16;
  121. sir[1] = (p & 0x00ff00) >> 8;
  122. sir[2] = (p & 0x0000ff);
  123. rinsum += sir[0];
  124. ginsum += sir[1];
  125. binsum += sir[2];
  126. rsum += rinsum;
  127. gsum += ginsum;
  128. bsum += binsum;
  129. stackpointer = (stackpointer + 1) % div;
  130. sir = stack[(stackpointer) % div];
  131. routsum += sir[0];
  132. goutsum += sir[1];
  133. boutsum += sir[2];
  134. rinsum -= sir[0];
  135. ginsum -= sir[1];
  136. binsum -= sir[2];
  137. yi++;
  138. }
  139. yw += w;
  140. }
  141. for (x = 0; x < w; x++) {
  142. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  143. yp = -radius * w;
  144. for (i = -radius; i <= radius; i++) {
  145. yi = Math.max(0,yp) + x;
  146. sir = stack[i + radius];
  147. sir[0] = r[yi];
  148. sir[1] = g[yi];
  149. sir[2] = b[yi];
  150. rbs = r1 - Math.abs(i);
  151. rsum += r[yi] * rbs;
  152. gsum += g[yi] * rbs;
  153. bsum += b[yi] * rbs;
  154. if (i > 0) {
  155. rinsum += sir[0];
  156. ginsum += sir[1];
  157. binsum += sir[2];
  158. } else {
  159. routsum += sir[0];
  160. goutsum += sir[1];
  161. boutsum += sir[2];
  162. }
  163. if (i < hm) {
  164. yp += w;
  165. }
  166. }
  167. yi = x;
  168. stackpointer = radius;
  169. for (y = 0; y < h; y++) {
  170. // Preserve alpha channel: ( 0xff000000 & pix[yi] )
  171. pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16)
  172. | (dv[gsum] << 8) | dv[bsum];
  173. rsum -= routsum;
  174. gsum -= goutsum;
  175. bsum -= boutsum;
  176. stackstart = stackpointer - radius + div;
  177. sir = stack[stackstart % div];
  178. routsum -= sir[0];
  179. goutsum -= sir[1];
  180. boutsum -= sir[2];
  181. if (x == 0) {
  182. vmin[y] = Math.min(y + r1,hm) * w;
  183. }
  184. p = x + vmin[y];
  185. sir[0] = r[p];
  186. sir[1] = g[p];
  187. sir[2] = b[p];
  188. rinsum += sir[0];
  189. ginsum += sir[1];
  190. binsum += sir[2];
  191. rsum += rinsum;
  192. gsum += ginsum;
  193. bsum += binsum;
  194. stackpointer = (stackpointer + 1) % div;
  195. sir = stack[stackpointer];
  196. routsum += sir[0];
  197. goutsum += sir[1];
  198. boutsum += sir[2];
  199. rinsum -= sir[0];
  200. ginsum -= sir[1];
  201. binsum -= sir[2];
  202. yi += w;
  203. }
  204. }
  205. bitmap.setPixels(pix,h);
  206. return (bitmap);
  207. }
  208. }



解析Xml,图形绘制

  1. package com.metek.blur;
  2.  
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5.  
  6. import android.content.Context;
  7. import android.content.res.XmlResourceParser;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.graphics.Canvas;
  11. import android.graphics.Paint;
  12. import android.os.AsyncTask;
  13. import android.os.SystemClock;
  14. import android.util.DisplayMetrics;
  15.  
  16. /**
  17. * 生成天气模糊背景图
  18. *
  19. */
  20. public class BlurWeatherImage {
  21. private static final String TAG = "BlurWeatherImage";
  22. private Bitmap bitmap = null;
  23. private Paint paint;
  24. private Canvas canvas;
  25. private FileOutputStream out = null;
  26. private float wRate;
  27. private float hRate;
  28. private int width;
  29. private int height;
  30. private Context context;
  31. private static final String IMAGENAME="ani_cloudy_night.png";
  32.  
  33. public BlurWeatherImage(Context context) {
  34. super();
  35. this.context = context;
  36. DisplayMetrics dm = context.getResources().getDisplayMetrics();
  37. width = dm.widthPixels;
  38. height = dm.heightPixels;
  39. bitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
  40. paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  41. canvas = new Canvas(bitmap);
  42. wRate = width / 720f;
  43. hRate = height / 1280f;
  44. }
  45.  
  46. /** 模糊图片 */
  47. public void blurImage() {
  48. BulurAsyncTask bat = new BulurAsyncTask();
  49. bat.execute();
  50. }
  51.  
  52. class BulurAsyncTask extends AsyncTask<Void,Void,Void> {
  53. protected Void doInBackground(Void... params) {
  54. analysisXml();
  55. return null;
  56. }
  57.  
  58. protected void onPostExecute(Void result) {
  59. super.onPostExecute(result);
  60. listener.drawEnd();
  61. }
  62.  
  63. }
  64.  
  65. public void analysisXml() {
  66. canvas.drawColor(0xff102d37);
  67. XmlResourceParser parser = context.getResources().getXml(R.xml.ani_cloudy_night);
  68. try {
  69. int event = parser.getEventType();
  70. while (event != XmlResourceParser.END_DOCUMENT) {
  71. String tagName = parser.getName();
  72. if (event == XmlResourceParser.START_TAG) {
  73. if (tagName.equals("view")) {
  74. int x = Integer.parseInt(parser.getAttributeValue(null,"x"));
  75. int y = Integer.parseInt(parser.getAttributeValue(null,"y"));
  76. int w = Integer.parseInt(parser.getAttributeValue(null,"w"));
  77. int h = Integer.parseInt(parser.getAttributeValue(null,"h"));
  78. String residname = parser.getAttributeValue(null,"resid");
  79. int resid = context.getResources().getIdentifier(residname.replace("@drawable/",""),"drawable",context.getPackageName());
  80. picture(bitmap,h,resid);
  81. SystemClock.sleep(100);
  82. }
  83. }
  84. event = parser.next();
  85. }
  86. } catch (Exception e) {
  87. e.printStackTrace();
  88. }
  89.  
  90. try {
  91. out = context.openFileOutput(IMAGENAME,Context.MODE_PRIVATE);
  92. bitmap.compress(Bitmap.CompressFormat.PNG,100,out);
  93. out = context.openFileOutput("blur_"+IMAGENAME,Context.MODE_PRIVATE);
  94. Bitmap blurBitmap = BlurUtils.fastblur(context,bitmap,80);
  95. blurBitmap.compress(Bitmap.CompressFormat.PNG,out);
  96. android.util.Log.i(TAG,IMAGENAME + "writer success");
  97. } catch (FileNotFoundException e) {
  98. e.printStackTrace();
  99. }
  100. }
  101.  
  102. /**
  103. * @param x
  104. * 元素x坐标
  105. * @param y
  106. * 元素y坐标
  107. * @param w
  108. * 元素宽度
  109. * @param h
  110. * 元素高度
  111. * @param resId
  112. * 资源id
  113. */
  114. public void picture(Bitmap bitmap,int x,int y,int w,int h,int resId) {
  115. Bitmap element = BitmapFactory.decodeResource(context.getResources(),resId);
  116. int scaleW = (int) (w * wRate);
  117. int scaleH = (int) (h * hRate);
  118. Bitmap scaled = Bitmap.createScaledBitmap(element,scaleW,scaleH,false);
  119. canvas.drawBitmap(scaled,x * wRate,y * hRate,paint);
  120. }
  121.  
  122. private OnDrawListener listener;
  123.  
  124. public interface OnDrawListener {
  125. /** 绘图结束 */
  126. public void drawEnd();
  127. }
  128.  
  129. public void setOnDrawListener(OnDrawListener listener) {
  130. this.listener = listener;
  131. }
  132. }

猜你在找的XML相关文章