当前位置:首页 » 安卓系统 » android图片绘制

android图片绘制

发布时间: 2025-03-27 22:23:37

‘壹’ Android音视频之使用OpenGL ES绘制图片

关于 OpenGL ES 的介绍,请先看上篇: Android 音视频之使用 OpenGL ES 绘制三角形 。

使用 OpenGL ES 绘制简单的几何形状还不够,OpenGL 更多地是用来显示而纹理图像,比如本地图片、相机画面。简单说,纹理(texture)就是一个图像或照片,它们可以被加载进 OpenGL 中。

OpenGL 中的纹理可以扰判用来表示图像、照片等,每个二维的纹理都由许多小缓缺改的纹理元素组成,它们是小块的数据,类似片段和像素。要使用纹理,最常用的方式是直接从一个图像文件加载数据。

纹理不会被直接绘制,它们要被绑定到纹理单元,然后把这些纹理单元传递给着色器。纹理映射的基本思想就是:首先为图元中的每个顶点指定恰当的纹理坐标,然后通过纹理坐标在纹理图中可以确定选中的纹理区域,最后将选中纹理区域中的内容根据纹理坐标映射到指定的图元上。

纹理的坐标系和顶点着色器的坐标系是不一样的。纹理坐标用浮点数来表示,范围 [0, 1],左上角坐标为 (0.0, 0.0),右上角坐标为 (1.0, 0.0)。注意:要将纹理坐标对应到正确的顶点上,才能使纹理正确扮银地显示。

定义顶点和纹理坐标,两者的顺序必须一一对应。

定义着色器。

加载图片到 OpenGL 中。

计算变换矩阵,采用 CenterInside 或者 CenterCrop 的方式显示。

显示图片。

源码在 GitHub 上。

参考资料:

‘贰’ Android的.9图制作

先来认识一下界面,并可以看到不管是横纵向拉升都使得图片失真

下面四个小选项分别是

从上图我们可以看到,不对图片进行任何修改,图片在某一方向拉伸时都是整体缩放的. 缩放同时,图片圆角也会跟埋圆着缩放,导致最终展示效果很差.

在编辑区可以看到要编辑的图片四周多了一像素的内容,这就是我们可以操作的区域了。
绘制小黑点 :只需要在四边需要的位置左键单击绘制小黑点,或者拖动绘制小黑线(其实是连续的多个小黑点)
删除小黑点 :按shift键,并左键单击或拖动进行删除操作,也可以按住鼠标右键进行擦除。

小黑点在png图最外层有一像素宽的边,除了四个顶角,小黑点可以绘制在png最外边的任一点处,
每个小黑点占据一像素
小黑点绘制之后。其规定一个区域,即小黑点处,垂直于所在边,且一像备液清素宽的区域

顶部:在水平拉伸的时候,保持其他位置不动,只在这个点代表区域做无限的延伸
左边:在竖直拉伸的时候,保持其他位置不动,只在这个点代表区域做无限的延伸
底部:在水平拉伸的时候,指定图片里的内容显示的区域
右边:在竖直拉伸的时候,指定图片里的内容显示的区域

从上图可以看出拉伸后我们希望的箭头区域没有失真,并且而且箭头距离右边距与上边距的距离没有变因此,保证了想要部分不失真

首先没有本质上的区别,下面通过一个例子来理解
假如有一个5px 5px大小的图片,横向上需要拉伸至20px
那么就是要横向拉升H=15px
假如横向上画了一个小黑点--则每个小黑点所代表区域拉伸h=15px h=H/1
假如横向上画了三个小黑点--则每个小黑点所代表区域拉伸h=5px h=H/3
因此 每条边上的每个小黑点所代表区域拉伸的宽度是一样的 *
所以要合理的布置我们的小喝仿前点以至png图能够达到我们想要的方向伸缩

点击左上file- save,保存文件,自动生成一张后缀名为“*.9.png”格式的图片,图片上下左右各增加了1px的黑线。

9patch图片是andriod app开发里一种特殊的图片形式,文件的扩展名为:.9.png
“点九”也是由于Android平台多种分辨率需适配的需求下,发展出来的一种独特的技术。它可以将图片横向和纵向随意进行拉伸,而保留像素精细度、渐变质感和圆角的原大小,实现多分辨率下的完美显示效果,同时减少不必要的图片资源,可谓切图利器。
.9.PNG确实是标准的PNG格式,只是在最外面一圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。特别说明,left和top边框中交叉部分是可拉伸部分,未选中部分是静态区域部分。right和bottom边框中交叉部分则是内容部分
无论是left和top,还是right和bottom都是把图片分成9块 (边角四块是不能缩放的,其他的四块则是允许缩放的),所以叫做9.PNG。
.9.png图片,android系统程序有对其优化的算法
参考
http://www.jianshu.com/p/3fd048644e3f
http://bbs.itheima.com/thread-251222-1-1.html
http://www.yimui.com/archives/117

‘叁’ android 如何重写imageview 让图片有圆角效果

android 自定义圆角ImageView以及锯齿的处理

看到很多人开发过程中要使用圆角图片时,解决方法有:


1.重新绘制一张图片


2.通过布局来配置


3.通过重写View来实现


其中1,2在这里就不讲了,重点讲讲方法三的实现。



实现一:通过截取画布一个圆形区域与图片的相交部分进行绘制,缺点:锯齿明显,设置Paint,Canvas抗锯齿无效。

package com.open.circleimageview.widget;


import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.Path;

import android.graphics.Rect;

import android.graphics.Region;

import android.util.AttributeSet;

import android.view.View;


public class CircleImageViewA extends View {


public CircleImageViewA(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}


public CircleImageViewA(Context context, AttributeSet attrs) {

super(context, attrs);

}


public CircleImageViewA(Context context) {

super(context);

}


private Bitmap bitmap;

private Rect bitmapRect=new Rect();

private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);

private Paint paint = new Paint();

{

paint.setStyle(Paint.Style.STROKE);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了

}

private Path mPath=new Path();

public void setImageBitmap(Bitmap bitmap)

{

this.bitmap=bitmap;

}

@Override

protected void onDraw(Canvas canvas) {


if(null==bitmap)

{

return;

}

bitmapRect.set(0, 0, getWidth(), getHeight());

canvas.save();

canvas.setDrawFilter(pdf);

mPath.reset();

canvas.clipPath(mPath); // makes the clip empty

mPath.addCircle(getWidth()/2, getWidth()/2, getHeight()/2, Path.Direction.CCW);

canvas.clipPath(mPath, Region.Op.REPLACE);

canvas.drawBitmap(bitmap, null, bitmapRect, paint);

canvas.restore();

}

}


实现二:通过PorterDuffXfermode 方式(注意要设置硬件加速,否则部分机子无效),优点:锯齿基本没有

package com.open.circleimageview.widget;


import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.graphics.Rect;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;


public class CircleImageViewB extends View {


public CircleImageViewB(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init();

}


public CircleImageViewB(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}


public CircleImageViewB(Context context) {

super(context);

init();

}


private Bitmap bitmap;

private Rect bitmapRect=new Rect();

private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);

private Paint paint = new Paint();

{

paint.setStyle(Paint.Style.STROKE);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了

}

private Bitmap mDstB=null;

private PorterDuffXfermode xfermode=new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);

private void init()

{

try {

if(android.os.Build.VERSION.SDK_INT>=11)

{

setLayerType(LAYER_TYPE_SOFTWARE, null);

}

} catch (Exception e) {

e.printStackTrace();

}

}

public void setImageBitmap(Bitmap bitmap)

{

this.bitmap=bitmap;

}


private Bitmap makeDst(int w, int h)

{

Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

Canvas c = new Canvas(bm);

Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

p.setColor(Color.parseColor("#ffffffff"));

c.drawOval(new RectF(0, 0, w, h), p);

return bm;

}

@Override

protected void onDraw(Canvas canvas) {


if(null==bitmap)

{

return;

}

if(null==mDstB)

{

mDstB=makeDst(getWidth(), getHeight());

}


bitmapRect.set(0, 0, getWidth(), getHeight());

canvas.save();

canvas.setDrawFilter(pdf);

canvas.drawBitmap(mDstB, 0, 0, paint);

paint.setXfermode(xfermode);

canvas.drawBitmap(bitmap, null, bitmapRect, paint);

paint.setXfermode(null);

canvas.restore();

}

}


‘肆’ android是否可以以画图的形式将图片画在某位置

可以。

1、在View的onDraw中获取canvas

java">@Override
protectedvoidonDraw(Canvascanvas){//onDraw中获取参数中的canvas
//TODOAuto-generatedmethodstub
super.onDraw(canvas);
}

2、获取图片,转化为Bitmap对象

//从资源文件中生成位图bitmap
Bitmapbitmap=BitmapFactory.decodeResource(getResources(),R.drawable.icon);

3、通过canvas的drawbitmap方法,把图片画到任意位置。

//Bitmap:图片对象,left:偏移左边的位置,top:偏移顶部的位置
//rawBitmap(Bitmapbitmap,floatleft,floattop,Paintpaint)
canvas.drawBitmap(bitmap,10,60,paint);//在10,60处开始绘制图片

‘伍’ android 鑳藉湪灞忓箷涓婄粯涓寮犲皬锲剧墖锛岀劧钖庨忔槑鑳屾櫙锛岃缮鑳芥搷浣滆兘鐪嫔埌镄勮儗鏅妗岄溃锲炬爣鎴栫▼搴忋

package com.qdsx.cml;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
//import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class TestdonghuaActivity extends Activity {
private ImageView tweenMM;
// private Animation animation;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tweenMM =(ImageView)findViewById(R.id.imageView1);
}

//娓愬彉
public void BtnAlphaOnClick(View view){
//this.doStartAnimation(R.anim.alpha_animation);
Animation b = new AlphaAnimation(0.1f, 1.0f);
b.setDuration(2000);
tweenMM.startAnimation(b);
}
//镞嬭浆
public void BtnrotateOnClick(View view){
//this.doStartAnimation(R.anim.rotate_animation);
Animation c = new RotateAnimation(0, 360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
c.setDuration(3000);
tweenMM.startAnimation(c);
}
//缂╂斁
public void BtnScaleOnClick(View view){
//this.doStartAnimation(R.anim.scale_animation);
Animation d = new ScaleAnimation(0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
d.setDuration(3000);
tweenMM.startAnimation(d);
}
//浣岖Щ
public void BtnTransalteOnclick(View view){
//this.doStartAnimation(R.anim.translate_animation);
Animation a= new TranslateAnimation(0, 100, 0, 100);
a.setDuration(5000);
a.setFillAfter(true);//浣垮浘鐗囩Щ锷ㄥ悗锲哄畾
tweenMM.startAnimation(a);
}

//寮濮嫔姩鐢绘柟娉
/* private void doStartAnimation(int animid){
animation = AnimationUtils.loadAnimation(this, animid);
animation.setFillAfter(true);//浣垮浘鐗囩Щ锷ㄥ悗锲哄畾
tweenMM.startAnimation(animation);
}*/
}

‘陆’ Android超简单实现炫酷的图片展示效果

这里的实现原理很简单,就是添加多个矩形路径,并不断的延长各个矩形路径的宽度(通过onDraw方法的递归实现),然后在矩形路径中绘制Bitmap即可。

1. 构建用于展示的Bitmap
这里我们选择在onSizeChanged方法中初始化Bitmap,因为当控件大小改变时方便我们重新计算所需展示Bitmap的大小。

2. 构建矩形裁剪区域并添加到Path中

3. 在对应的路径中绘制出Bitmap
这里使用Canvas的clipPath方法将画布裁切成路径的形状,然后在裁切后的画布上绘制图片。

4. 利用递归实现动画效果

5. 当图片完全显示时替换图片
图片完全显示也是cilpWidth>控件宽度的时候。

扫描式图片展示

‘柒’ android画一张图片,缩放显示并且放大不失真

这个问题涉及图片呈现的一整套方案。归纳而言这个问题是:给定任意尺寸的图片如何在任意尺寸分辨率的机器上显示?并且能够保持图片原来的清晰度。一般采用如下方案来解决这个问题:
1、首先给原图片创建一块内存缓存副本。如果不创建缓存的话,那么任何一次图片的剪切、缩放等操作都将丢失图片信息,使得保持原有图片的滋味那是不可能的。当然对于一般的程序而言,这个操作只需要调用简单的API即可完成。例如Android,只需要创建一个对应图片的Bitmap对象即可。
2、如果想要在设备显示的初始化状态图片即为满屏,那么必须调用相关API动态获得设备的分辨率。然后按设备分辨率的大小对图片进行剪切并显示到设备上。
注意:在获得图片分辨率后,如果分辨率大于图片,那不用说,直接显示图片就好。但是如果小于图片,此时有多种选择。可以将图片缩放至屏幕分辨率(图片纵横比可能失真)也可以选择剪切图片的一部分显示到屏幕上。
3、对图片进行缩放或者移动
我们在图片第一次显示的时候无论是选择缩放还是剪切,都要记录下图片被缩放的比例或者剪辑的范围。这样在用户再次移动或者缩放的时候,根据之前的缩放比例和移动坐标,计算当前应该移动的位置和缩放比例。并且根据计算结果对缓存的图片进行剪辑并显示到屏幕上。
其实整个过程可以概括为如下流程:
——>图片的初始缩放比例和显示起点坐标——>用户触发缩放或者移动操作——>计算新的图片缩放比例和显示起点坐标——>根据新的缩放比例和显示起点坐标剪辑缓存图片并绘制到屏幕上......

热点内容
流程审批数据库设计 发布:2025-03-31 08:35:44 浏览:569
中国版dream服务器怎么进入 发布:2025-03-31 08:32:11 浏览:75
android44小米3 发布:2025-03-31 08:32:00 浏览:892
java消除 发布:2025-03-31 08:30:40 浏览:250
南京云服务器平台 发布:2025-03-31 08:30:32 浏览:726
平方的速算法 发布:2025-03-31 08:27:25 浏览:534
光存储储备 发布:2025-03-31 08:16:37 浏览:155
服务器hypixel地址 发布:2025-03-31 08:12:18 浏览:138
国内比较便宜的云服务器 发布:2025-03-31 08:03:23 浏览:252
电视机内存有哪些配置 发布:2025-03-31 08:02:36 浏览:681