怎样在c bitmapp上的绘图后进行清屏回到原来的状态

android(19)
invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
(1)(2)(2)(1)(1)(1)(1)(19)(1)Android画图之Bitmap(二) - 封碎 - ITeye博客
博客分类:
前面一篇博文
介绍了简单的把
画到屏幕上,以及缩放
以铺满屏幕。对
的操作还有很多。比如截取
的部分区域,可以使用
mBitmap = Bitmap.createBitmap(bmp, 100, 100, 120, 120);
这句代码从
像素区域放到新的
,前面一篇已经涉及到了,可以用
Bitmap.createScaledBitmap()
法根据给定的
一个新的,缩放后的
Bitmap mBitmap = Bitmap.createScaledBitmap(bmp, mScreenWidth, mScreenHeight, true);
mScreenWidth
mScreenHeight
是屏幕的宽度和高度,这里就将
拉伸到整个屏幕。
createBitmap
,都会分配新的内存,带来资源的
消耗,所以用
createBitmap
虽然简单方便,但是不是最优方
法。介绍一个比较好点的方法,不用创建新的
在画的时候直接缩放或者剪切。
canvas.drawBitmap(mBitmap, null, new Rect(0, 0, 200, 200), null);
对象表示一个矩形区域,从
之间的矩形区域。这段代码将把
缩放并绘制到屏幕上的
之间的区域。
这个方法还有第二个参数我给的是
,其实这个参数也是个
对象,表示源
。把图片的某个区域拿出来画到屏幕的指定区域。
canvas.drawBitmap(mBitmap, new Rect(100, 100, 300, 300), new Rect(100, 100, 200, 200), null);
区域拿出来,自动缩放并画到屏幕的
的处理,上面介绍的
是最简单的两种,平移和缩放。而要是需要更复杂的处理,比如旋转和倾斜,就得使用
了。下面几篇将介绍
在画图中的使用。
论坛回复 /
(1 / 8164)
浏览: 515688 次
来自: 深圳
少了一个构造函数
06-30 17:39:19.193: E/AndroidRu ...
为什么报错哦
只是获取activity的名字而已,
没有实例。
重写下面两个函数EditText完全作废,点击没有反应没有光标 ...【转载】浅谈J2me游戏如何快速移植到Android -
- ITeye博客
博客分类:
《J2me小白转正记》
--------------浅谈J2me游戏如何快速移植到Android
(关于这篇文章~非常的尴尬~骨头就不细说了~当然了咱没理由怪别人~还得修炼哈哈)
小白:“老大,你让做的三个J2me游戏搞定了,请看DEMO。”
老大:“恩,不错,小白,你知道Android这个平台吧?”
小白:“恩,听过。听说和J2ME有很多共同点。”
老大:“(一阵奸笑)很多共同点是吧?”
小白:“恩。”
老大:“那好,你把这几个J2ME游戏给我移植到Android上去。”
小白:“……”
很多J2ME开发者可能都会遇到这样的临时性需求。其实J2ME程序往Android移植,并不是特别麻烦。
经过一番认真学习,小白开始整理起了笔记……
高级UI界面
J2ME的高级用户界面比较鸡肋,在现在大多数的应用里都看不到,多数稍微复杂点的界面都是手工画,或是用一些开源的高级UI库,但Android则不同,它的UI实用、方便,而且很美观,基本无需改动且定制方便。
一 设备差异
虽说普通的手机性能越来越高,屏幕也越来越大,但平均而言,运行J2ME的手机从性能和屏幕分辨率及附属功能来说不及Android手机。拿入门的HTC G1来说,CPU为528MHz,屏幕为3.17英寸触摸屏、HVGA 480×320像素,192MB RAM和256MB ROM。所以从J2ME移植到Android的程序可以暂时不考虑性能问题。
但要充分发挥Android手机的特点。要注意一下几点:
比如应用UI的布局可以更加自由,输入更加灵活,网络应用注意发挥3G、WIFI的速度优势。
游戏要注意可适当的用效率换效果,可增加动画、音效、背景音乐的质量,图片元素的大小,发挥高分辨率手机的优势,强大的运算能力可以让开发人员编写基于OpenGL的3D游戏,可以用一些吃CPU但效果不错的开发包,如Box2D仿真物理引擎开发包。
可以结合GPS定位、重力感应、话筒、指南针、触笔的压力感应等等让游戏的效果更加逼真。
J2ME与Android系统的常用类、方法对比
J2ME与Android系统的常用类、方法对比
Android系统
Activity类
Image.createImage(path);
BitmapFactory.decodeResource(getResources(),R.drawable.map0);
Graphics类
Displayable类
keyPressed()
keyRepeated()
keyReleased()
onKeyDown()
onTracKballEvent()
pointerPressed(),
pointerReleased(),
pointerDragged()
onTouchEvent()
System.out.printlt()
生命周期-开始
startApp(),活动状态,启动时调用,初始化。
onCreate(),返回时也会调用此方法。
onCreate()后调用onStart(),
onStart()后调用onResume(),
生命周期-暂停
PauseApp(),暂停状态,如来电时,调用该接口。
生命周期-销毁
destroyApp(),销毁状态,退出时调用。
onStop(),程序不可见时调用onDestroy(),程序销毁时调用
高级UI组件由内部刷新实现。
低级UI,canvas中通过调用线程结合repaint()来刷新,让线程不断循环
高级UIHandler类通过消息的机制刷新
onDraw()刷新接口
低级UI开发者用线程控制更新,在lockCanvas()和unlockCanvasAndPost()方法之间绘制
Record Management System (RMS)
SQLite数据库
SharedPreferences类
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipW = g.getClipWidth();
int clipH = g.getClipHeight();
g.clipRect(x, y, width, height);
g.setClip(clipX, clipY, clipW, clipH);
canvas.save();
canvas.clipRect(x,y,x+width, y+height);
cavnas.resave();
游戏中清屏
paint.setStyle(Style.FILL);
canvas.drawRect(new Rect(0, 0, getWidth(), getHeight()), paint);
canvas.drawColor(Color.BLACK);
游戏开发包
javax.microedition.lcdui.game包
GameCanvas类
LayerManager类
TiledLayer类
无专门针对游戏的开发包,可以直接拿来主义,将J2ME的开发包稍作修改
Player s =Manager.createPlayer(InputStream);
s.prepare(); //创建
s.start();//播放
s.stop();//暂停
s.stop();//关闭
s.release();//释放
MediaPlayer类处理背景音乐
SoundPool类处理一些简单的音效
Canvas中SetFullScreenMode()
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
获得屏幕尺寸
Canvas类的getHeight()和getWidth()
Display d = getWindowManager().getDefaultDisplay();
screenWidth = d.getWidth();
screenHeight = d.getHeight();
Image bufImage=Image.createImage(bufWidth, bufHeight);
Graphics bufGraphics=bufImage.getGraphics();
Bitmap carBuffer = Bitmap.createBitmap(bufWidth, bufHeight, Bitmap.Config.ARGB_4444);
Canvas carGp = new Canvas(carBuffer);
小白找到Android中对应的J2ME相关的替代类和替代方法后,开始噼里啪啦的改代码了。没过多久,首个俄罗斯方块算是移植成功。当他开始移植下一款游戏时,发现又要重复的改那些代码……
“可不可以减少代码的改动呢?”小白问自己。“可否用Android的相关代码构造一些和J2me里功能类似的代码呢?”
原则:尽量少改动J2ME项目的代码。用Android中对应的类改写成J2ME中的方法和类,减少以后移植的工作量,甚至实现无缝移植。
“或许我可以构造一个名为MIDlet实为Activity的类,这样J2me中的入口类就不用改动了”
用Activity类改装的MIDlet类:
public abstract class MIDlet extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startApp();
public abstract void destroyApp(boolean unconditional);
public String getAppProperty(String key) {
public abstract void startApp();
public void notifyDestroyed() {
public void notifyPaused() {}
public void pauseApp() {}
public void platformRequest(String URL) {}
public void resumeRequest() {}
MIDlet类我们解决了,接下来就是非常重要的Canvas类了。
J2me里的Canvas类相当于Android体系中的SurfaceView类,都是负责绘制显示界面的,游戏的大循环一半也在这两个类里实现,也就是都会实现Runnable类,更新逻辑和更新界面都在此类的大循环中处理。
Graphics类在J2me里负责绘图和排版样式等。
我们可以用Android里的Canvas类和Paint类共同组合一个Android里的Graphics类,如Graphics类的构造函数可这样定义:
public Graphics(Bitmap bitmap) {
this.bitmap =
this.canvas = new Canvas(bitmap);
this.canvas.clipRect(0, 0, bitmap.getWidth(), bitmap.getHeight());
this.canvas.save(Canvas.CLIP_SAVE_FLAG);
this.paint = new Paint();
this.clip = canvas.getClipBounds();
Graphics里可以设置居中方式,在Android体系里我们用Paint类来实现相同的效果,例如:
public void setAlign(int align)
if(LEFT == align
||(Graphics.LEFT | Graphics.TOP) == align
||(Graphics.LEFT | Graphics.BOTTOM) == align)
paint.setTextAlign(Align.LEFT);
}else if(HCENTER == align
||(Graphics.HCENTER|Graphics.TOP) == align)
paint.setTextAlign(Align.CENTER);
}else if(RIGHT == align
||(Graphics.RIGHT | Graphics.TOP) == align)
paint.setTextAlign(Align.RIGHT);
所有的绘制方法也同样沿用J2me中的方法名,用Android体系的代码完成方法体,达到无缝移植。以绘制、填充矩形为例:
public void fillArc(int x,int y,int width,int height, int startAngle,int arcAngle) {
zhengalways
浏览: 4984 次
来自: 南京Android-UI(7)
android中如果要绘制2d图形需要有四个基本组件:
1,Bitmap :相当于画布。基于它之上画图。还可以是:Rect、RectF、text。
2,Canvas:相当于画家。在画布上管理绘制过程,提供绘图方法。
3,Paint:相当于画笔,可以设置画笔的颜色,粗细,类型等。
4,Drawable:包含绘制要素。,如形状,路径,文本,图像等。用于展示图像。
可以绘制图像的对象有三个:
1,自定义View,重写onDraw()方法,获取到其中的Canvas实例。
public class AddView extends View {
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
2,定义一个Bitmap对象绘图。new一个Cancas对象,并传入bitmap实例。
Bitmap bitmap=Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888)
Canvas canvas=new Canvas(bitmap)
3,使用SuefaceView对象绘制动态图像。
SurfaceHolder surfaceHolder= surfaceView.getHolder();
Canvas canvas=surfaceHolder.lockCanvas();
surfaceHolder.unlockCanvasAndPost(canvas);
不管是哪一种对象都是获得其中的Canvas(画家)对象。
那么,2d绘图中需要注意的有哪些呢?通过我自己亲身试险和同行朋友的经验总结了以下几个方面:
1,自定义view继承的对象不光view
当我们需要画一个图的时候,一般情况下会继承view,然后重写onDraw()方法。
但是有些时候,我们并不能继承这个没有任何特征的view。有时候我们需要继承layout或者textview等等。
那么这个时候问题就来了。例如,我们如果要在grouplayout上画图,就有一个问题。grouplayout的视图属性是依赖于子view。
也就是说,我给grouplayout设置了背景色,其实是没有作用的,而依赖于它之上的子view设置的背景色才被用户所看到。
所以,如果我们要在grouplayout上画一个图,那么就算画出来了它也是不会给你显示的。
那么这个时候我们应该怎么办呢?
这里要提到一个属性:
//设置不重绘为false
setWillNotDraw(false);
只要你的自定义view继承view或者以view为父类的控件,都是可以设置这条属性的。
顾名思义,这条属性的意思就是视图不重新绘制。
android系统默认的是true。也就是默认不重新绘制,这导致了如果你要在类似grouplayout这样的视图上绘图的时候,它是不会重新绘制的,也就是显示不出来。
所以我们要设置这么一条属性,告诉系统,这个view需要重新绘制。
2,只有onDraw需要重写吗?
如小标题,答案是no!
继承了view后重写onDraw会得到Canvas对象,用于重绘。但是问题是重绘的一切位置依据是根据坐标来的。你如何获得应该在哪里重绘的依据呢?
不要告诉我说默认坐标(0,0)。这明显是不符合要求的,也满足不了要求的。
也不要告诉我根据getWidth()和getHeight()来获得,如果xml中配置的是自适应高度或者根据父类显示怎么办呢?而且,最重要的是在view还没有显示出来的时候,它们的值是null,而我们需要根据它们的值来绘图。所以不可能先出图再获得值。
那么,还要重写第二个view中的方法:protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
这个方法会返回给你一个宽高的测量规范。不是宽高。
那么它有什么用呢?它怎么获得控件的宽高或者父类的宽高呢?
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
在onMeasure方法中做以上代码的处理,就可以得到宽度。同理,高度也一样。
不过当在xml中设置根据内容显示的时候(wrap_content),该值是无效的,也就是说当自适应宽高的时候,获取不到有效的宽高值。
这时候应该怎么办呢?
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthS
width = 60;
通过MeasureSpec.getMode来获取当前view在xml中设置的值是否是有效的。
如果该值有效,说明xml中设置了明确的大小,或者设置了根据父类设置宽高(match_parent)。
如果该值无效则我们给一个默认值。
获得了view的宽高,绘图就有可靠的依据了。
另外,在这个方法中,获得到了宽度或者高度,如果绘制的图是正方形的话可以用:
setMeasuredDimension(width, width);
这个属性来将宽高设置成一样。达到正方形的目的。
3,重载onMeasure()方法后抛出异常了
当我们重写onMeasure()方法后发现报了这样一个错误:
java.lang.IllegalStateException: onMeasure() did not set the measured dimension by calling setMeasuredDimension()
暴力的翻译过来就是告诉你没有调用setMeasuredDimension()方法。
只要重载onMeasure()方法就必须调用setMeasuredDimension()方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthS
height = heightS
setMeasuredDimension(width, height);
4,自定义view的坐标是四个象限吗?
先来看个图:
如果刚刚接触2d绘图的程序员会天真的以为android屏幕内的坐标系还和我们数学课本上的一样,那你就错了。
正确的坐标系是这样的:
没错,android屏幕上的坐标系就只这样的,以左上角为原点(0,0),向右向下正数无线增大。
也就是说,android坐标系没有负象限。如果你将绘图的坐标强行设置成负数它只会跑出父类去。
弄清了坐标系,那么计算位置啥的都比较好说了。
4,自定义view依附于屏幕吗?
自定义view的宽高起始点和被控制的范围大小很多不理解的程序员以为是以屏幕为依据的。例如,view的宽设置成了match_parent,这个时候理论上来说,它的宽度的确是屏幕的宽度。
但是如果,这个view外面有一个父布局,那么它的宽只能和父类一样打。(这tm废话)需要注意的是,这时候,自定义view的移动就要以父类作为基准了,计算高度或者获取坐标都要以父类的左上角为起点来计算。
就算你在自定义view中看到的绘图室全屏幕显示的,但是只要依赖了非屏幕的父布局,它就不再是全屏幕显示的了。
所有以父类为依据的数值都要做相应的改变了。
通俗点说,就是在自定义view中绘图的时候,我们不能莽撞的去获取屏幕的宽高来计算,而是以获取父布局的宽高来作为依据。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:112156次
积分:1602
积分:1602
排名:千里之外
原创:51篇
评论:63条
文章:13篇
阅读:6700
文章:26篇
阅读:72332
(1)(1)(1)(10)(3)(35)

我要回帖

更多关于 对bitmap进行压缩 的文章

 

随机推荐