1. 何为 9patch图 ?

    它是一个对png图片做处理的一个工具,能够为我们生成一个"*.9.png"的图片;所谓"*.9.png"这是Android os里所支持的一种特殊的图片格式,用它可以实现部分拉伸;这种图片是经过"9patch"进行特殊处理过的,如果不处理的话,直接用PNG图就会有失真,拉伸不正常的现象出现。

2. 9patch图细节,说明如下:

 

1号黑色条位置向右覆盖的区域表示图片纵向拉伸时,只拉伸该区域

2号黑色条位置向下覆盖的区域表示图片横向拉伸时,只拉伸该区域

3号黑色条位置向左覆盖的区域表示图片纵向显示内容的区域(在手机上主要是文字区域)

4号黑色条位置向上覆盖的区域表示图片横向显示内容的区域(在手机上主要是文字区域)

没有黑色条的位置覆盖的区域是图片拉伸时保持不变(比如,如果图片的四角为弧形的时候,当图片被任意拉伸时,四角的弧形都不会发生改变)

右边3个红色图形区域为显示当前拉伸效果

2.使用9patch:

(1)启动9patch图:

在你Android SDK 路径下 X:/android sdk/tools ,你会找到一个 【draw9patch.bat】,没错这就是9patch、官方名 NinePatch ;

双击这个"draw9patch.bat",如下:

(2)提示导入一张png图片,然后真正进入"9patch"的操作界面(如下图):   

图1:

序列 ① :在拉伸区域周围用红色边框显示可能会对拉伸后的图片产生变形的区域,如果完全消除该内容则图片拉伸后是没有变形的,也就是说,不管如何缩放图片显示都是良 好的。 (实际试 发现NinePatch编辑器是根据图片的颜色值来区分是否为bad patch的,一边来说只要色差不是太大不用考虑这个设置。) 

序列 ② :区域是导入的图片,以及可操作区域。

序列 ③ :这里 zoom:的长条bar 是对导入的图放大缩小操作,这里的放大缩小只是为了让使用者更方便操作,毕竟是对像素点操作比较费眼,下面的 patch scale 是序列 ④区域中的三种形态的拉伸后的一个预览操作,可以看到操作后的图片拉伸后的效果。

序列 ④: 区域这里从上到下,依次为:纵向拉伸的效果预览、横向拉伸的效果预览,以及整体拉伸的效果预览

序列 ⑤: 这里如果你勾选上,那么当你鼠标放在 ② 区域内的时候并且当前位置为不可操作区域就会出现lock的一张图,就是显示不可编辑区域 ;

序列 ⑥: 这里勾选上,那么在④ 区域中你就会看到当前操作的像素点在拉伸预览图中的相对位置和效果。

序列 ⑦: 在编辑区域显示图片拉伸的区域;

(3)如何操作:

       鼠标左键选取需要拉伸的像素点;  shift+鼠标左键取消当前像素点。

(4)操作区域:

                                   

大家看到导入的png图片默认周围多了一像素点,也就是这一圈一像素点就是咱们的可操作区域。因为下方和右方可操作区域是指定内容的显示区域,属于可选区域,可不予理会;但是要注意内容区域的标记不能有间断,也就是说标记要连续且仅有一处,否则.9.png图片在放入项目下会报错。

      主要大家注意Left 和 top 操作区域;

 

     Top操作区域的一排像素点,表示横向拉伸的像素点; 

     Left操作区的一排像素点,表示纵向拉伸的像素点;

(5)下图是我对图片的操作:

图2:

大家看到上方和左边的黑色像素了么?对,这些是我手动操作的地方,我这里是想让此png图像拉伸操作的时候,只是中间区域被拉伸。选择上方中间区域是为了横向拉伸的时候选取的拉伸像素点,左边则是纵向拉伸的;

  

那么大家现在回头看一眼(图1)然后对比(图2),看到区别了吧!很明显,(图1)我们没有任何操作,默认整体拉伸,那么拉伸的效果很明显的失真了...而(图2)我们指定了拉伸的像素点所以只是中间的被拉伸,图片的花边我们保留不拉伸这样看起来就好太多啦 娃哈哈、

然后通过“9妹”就可以保存出来一张“*.9.png”图片,我们放在android 项目的res 下的 drawable 下就可以拉!

(6)现在我就可以跟大家讲下使用" *.9.png"的好处:

      在我们手机游戏开发的过程中,我们最关系的是生成的安装文件、比如j2me 的jar 包,塞班的sis、sisx 以及咱们andrid中的apk都希望打包后的包越小越好、虽然现在的手机趋向于智能了,但是毕竟手机的容量和内存还是有限、身为移动设备开发者的我们对此都很看重,那么通过"9妹"处理后的图片我们就可以省去不少的内存和容量。

 •省精力和时间!

    如果我们有一张50*50的类似上面那种带花边的png图片,那么我们在android或者大分辨率的机器上使用的画,肯定需要对其处理,那么要不就是让美工的mm们给咱们重新做一张,那么通过"9妹"处理得到的“*.9.png”就会省去美工的负担了。

  •省内存!

   如果不想用代码来对其小图进行缩放来再次使用(因为考虑会失真),那么可能会多加了图片,这样一来游戏包的大小就会增加了,几K—几十K不等,而利用"9妹"处理的就省去了这些麻烦。

  •减少代码量! 

  有些童鞋该说啦,我用代码一样能实现(图2)的效果不失真,OK,我也知道。当初我在J2ME平台做RPG的时候也是利用设置可视区域等代码来实现的,但是如果你用“.9.png”的方式就更简单!!!

(7)下面我们来看看代码如何实现此格式的方式和效果吧:

 package com.himi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class MySurfaceView extends SurfaceView implements Callback, Runnable {
private Thread th = new Thread(this);
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;
private Bitmap bmp_old;
private Bitmap bmp_9path;
private NinePatch np;
public MySurfaceView(Context context) {
super(context);
this.setKeepScreenOn(true);
bmp_old = BitmapFactory.decodeResource(getResources(), R.drawable.himi_old);
bmp_9path = BitmapFactory.decodeResource(getResources(), R.drawable.himi_9path);
np = new NinePatch(bmp_9path, bmp_9path.getNinePatchChunk(), null);
//创建一个ninePatch的对象实例,第一个参数是bitmap、第二个参数是byte[],这里其实要求我们传入
//如何处理拉伸方式,当然我们不需要自己传入,因为“.9.png”图片自身有这些信息数据,
//也就是我们用“9妹”工具操作的信息! 我们直接用“.9.png”图片自身的数据调用getNinePatchChunk()即可
//第三个参数是图片源的名称,这个参数为可选参数,直接null~就OK~
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setAntiAlias(true);
setFocusable(true);
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v("Himi", "surfaceCreated");
th.start();
}
/**
* @author Himi
*/
public void draw() {
canvas = sfh.lockCanvas();
canvas.drawColor(Color.BLACK);
RectF rectf_old_two = new RectF(0, 50, bmp_old.getWidth() * 2, 120 + bmp_old.getHeight() * 2);//备注1
RectF rectf_old_third = new RectF(0, 120 + bmp_old.getHeight() * 2, bmp_old.getWidth() * 3,
140 + bmp_old.getHeight() * 2 + bmp_old.getHeight() * 3);
// --------下面是对正常png绘画方法-----------
canvas.drawBitmap(bmp_old, 0, 0, paint);
canvas.drawBitmap(bmp_old, null, rectf_old_two, paint);
canvas.drawBitmap(bmp_old, null, rectf_old_third, paint);
RectF rectf_9path_two = new RectF(250, 50, 250 + bmp_9path.getWidth() * 2, 90 + bmp_9path.getHeight() * 2);
RectF rectf_9path_third = new RectF(250, 120 + bmp_9path.getHeight() * 2, 250 + bmp_9path.getWidth() * 3,
140 + bmp_9path.getHeight() * 2
+ bmp_9path.getHeight() * 3);
canvas.drawBitmap(bmp_9path, 250, 0, paint);
// --------下面是".9.png"图像的绘画方法-----------
np.draw(canvas, rectf_9path_two);
np.draw(canvas, rectf_9path_third);
sfh.unlockCanvasAndPost(canvas);
}
public void run() {
// TODO Auto-generated method stub
while (true) {
draw();
try {
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.v("Himi", "surfaceChanged");
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v("Himi", "surfaceDestroyed");
}
}

下图是模拟器中的效果图:

左边是正常png的缩放不同大小的情况,右边是咱们的9妹处理过的“*.9.png”,娃哈哈,怎么样,效果明显不一样吧!

自定义控件(视图)2期笔记08:自定义控件之 9patch图说明的更多相关文章

  1. MYSQL视图的学习笔记

    MYSQL视图的学习笔记,学至Tarena金牌讲师,金色晨曦科技公司技术总监沙利穆 课程笔记的综合. 视图及图形化工具   1.       视图的定义 视图就是从一个或多个表中,导出来的表,是一个虚 ...

  2. JAVA自学笔记08

    JAVA自学笔记08 1.构造方法私有,外界就不能再创建对象 2.说明书的制作过程 1)写一个工具类,在同一文件夹下,测试类需要用到工具类,系统将自动编译工具类:工具类的成员方法一般是静态的,因此在测 ...

  3. 机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集

    机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集 关键字:FPgrowth.频繁项集.条件FP树.非监督学习作者:米 ...

  4. CS229 笔记08

    CS229 笔记08 Kernel 回顾之前的优化问题 原始问题为: \[ \min_{w,b} \frac{1}{2}||w||^2\\[1.5em] {\text{s.t.}}y^{(i)}\le ...

  5. C++ GUI Qt4学习笔记08

    C++ GUI Qt4学习笔记08   qtc++signal图形引擎文档 本章介绍Qt的二维图形引擎,Qt的二维图形引擎是基于QPainter类的.<span style="colo ...

  6. Java:并发笔记-08

    Java:并发笔记-08 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 7. 共享模型之工具-1 7.1 线程池 1. 自定义线程池 步骤1:自定义拒绝策略接 ...

  7. Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图

    原文:Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图 前面两期学习了 ViewAnimator及其子类ViewSwitcher的使用,以及ViewSwitcher的 ...

  8. 自定义控件(视图)2期笔记09:自定义视图之继承自ViewGroup(仿ViewPager效果案例)

    1. 这里我们继承已有ViewGroup实现自定义控件,模拟出来ViewPager的效果,如下: (1)实现的效果图如下: (2)实现步骤: • 自定义view继承viewGroup • 重写onLa ...

  9. 自定义控件(视图)2期笔记01:自定义控件之自定义View的步骤

    1. 根据Android Developers官网的介绍,自定义控件你需要以下的步骤: (1)创建View (2)处理View的布局 (3)绘制View (4)与用户进行交互 (5)优化已定义的Vie ...

随机推荐

  1. Day12(补充) Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

  2. NodeJs开发学习目录

    1.Nodejs基本概念及Nodejs.npm安装测试[2014-06-06] 2.开发工具简介(主要介绍Sublime Text使用) [2014-06-06] 3.Sublime text插件安装 ...

  3. NandFlash驱动框架

    1.首先和前面的几个驱动程序相似,需要分配一个nand_chip结构体 s3c_nand = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); 然后填充该结 ...

  4. CSS预处理器之SASS用法指南

    CSS预处理器之SASS用法指南 一.什么是SASS Sass是是一种基于ruby编写的CSS预处理器,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 诞生于200 ...

  5. AVL树的算法思路整理

    http://www.cnblogs.com/heqile/archive/2011/11/28/2265713.html 看完了<数据结构与算法分析(C++描述)>的4.4节AVL树,做 ...

  6. h.264语法结构分析

    NAL Unit Stream Network Abstraction Layer,简称NAL. h.264把原始的yuv文件编码成码流文件,生成的码流文件就是NAL单元流(NAL unit Stre ...

  7. Android Studio使用远程依赖时下载不了jar包的解决方法

    使用AS很大的一个好处就是可以使用在线jar包,只需在引用jar包的时候在版本后加上+,比如: compile 'com.facebook.fresco:fresco:0.1.0+' 这样不用在jar ...

  8. LVS+Keepalived+Nginx+Tomcat高可用负载均衡集群配置(DR模式,一个VIP,多个端口)

    一.概述 LVS作用:实现负载均衡 Keepalived作用:监控集群系统中各个服务节点的状态,HA cluster. 配置LVS有两种方式: 1. 通过ipvsadm命令行方式配置 2. 通过Red ...

  9. unicode编码、字符的转换和得到汉字的区位码

    一:unicode编码.字符的转换截图 二:unicode编码.字符的转换代码 using System; using System.Collections.Generic; using System ...

  10. Delphi NativeXml用法攻略 转

    NativeXml可以在官网上下载,下载后将文件夹放在指定地方,打开DELPHI在其环境变量中引用NativeXml路径,然后在程序中引用NativeXml单元,我们就可以使用NativeXml了. ...