package eoe.demo;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class PhotoProcess extends Activity{
public static final int FIRST_PIC = 0;
public static final int SECOND_PIC = 1;
public static final int MAX_WIDTH = 240;
public static final int MAX_HEIGHT = 180;
private Button btnSelect,btnSelect2;
private ImageView srcImageView, dstImageView;
private Bitmap srcBitmap, dstBitmap;
private Uri imageUri;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.process);
this.btnSelect = (Button)this.findViewById(R.id.btn_select);
btnSelect.setOnClickListener(clickListener);
this.btnSelect2 = (Button)this.findViewById(R.id.btn_select2);
btnSelect2.setOnClickListener(clickListener2);
srcImageView = (ImageView)this.findViewById(R.id.img_src);
dstImageView = (ImageView)this.findViewById(R.id.img_dst);
}
private View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 启动Gallery应用
Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, FIRST_PIC);
}
};
private View.OnClickListener clickListener2 = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 启动Gallery应用
Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SECOND_PIC);
}
};
public boolean onCreateOptionsMenu(Menu menu){
//super.onCreateOptionsMenu(menu);
//MenuInflater menuInflater = new MenuInflater(this);
//menuInflater.inflate(R.layout.image, menu)
menu.add(Menu.NONE,1,Menu.NONE,"复制");
menu.add(Menu.NONE,2,Menu.NONE,"变换");
menu.add(Menu.NONE,3,Menu.NONE,"亮度");
menu.add(Menu.NONE,4,Menu.NONE,"合成");
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item){
int id = item.getItemId();
switch(id){
case 1:
//复制一个图像
if(srcBitmap != null){
dstBitmap = getDstImage(null);//这里没有变换
dstImageView.setImageBitmap(dstBitmap);
}
break;
case 2:
//对复制后的图像进行变换
if(srcBitmap != null){
dstBitmap = transferImage();
dstImageView.setImageBitmap(dstBitmap);
}
break;
case 3:
//改变图像的色彩
if(srcBitmap != null){
dstBitmap = ajustImage();
dstImageView.setImageBitmap(dstBitmap);
}
break;
case 4:
if(srcBitmap != null && dstBitmap != null){
dstBitmap = compositeImages();
dstImageView.setImageBitmap(dstBitmap);
}
break;
}
return true;
}
private Bitmap getDstImage(Matrix matrix){
Bitmap bmp = null;
//下面这个Bitmap中创建的函数就可以创建一个空的Bitmap
//返回的是一个可以改变的Bitmap对象,这样我们后面就可以对其进行变换和颜色调整等操作了
bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//创建Canvas对象,
Canvas canvas = new Canvas(bmp);
//创建Paint对象,这里先不用
Paint paint = new Paint();
//在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
if(matrix != null){
//如果matrix存在,则采用变换
canvas.drawBitmap(dstBitmap, matrix, paint);
}else{
canvas.drawBitmap(srcBitmap, 0, 0, paint);
}
return bmp;
}
/**
* 重载getDstImage函数,传入定制的Paint对象
* @param matrix
* @param paint
* @return
*/
private Bitmap getDstImage(Matrix matrix, Paint paint){
Bitmap bmp = null;
//下面这个Bitmap中创建的函数就可以创建一个空的Bitmap
//返回的是一个可以改变的Bitmap对象,这样我们后面就可以对其进行变换和颜色调整等操作了
bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//创建Canvas对象,
Canvas canvas = new Canvas(bmp);
//在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
if(matrix != null){
//如果matrix存在,则采用变换
canvas.drawBitmap(dstBitmap, matrix, paint);
}else{
canvas.drawBitmap(srcBitmap, 0, 0, paint);
}
return bmp;
}
/**
* 为了放大缩小、旋转图像,我们要使用Matrix类。Matrix类是一个三维矩阵。
* 在Android屏幕中,图像的每个像素对应都是一个坐标,一个坐标由x/y/z组成
* cosX -sinX translateX
* sinX cosX translateY
* 0 0 scale
* 第一行的值,影响着x坐标。比如 1 0 0 =>x = 1*x + 0*y + 0*z
* 第二行的值,影响着y坐标。比如0 1 0 => y = 0*x + 1*y + 0*z
* 第三行的值,影响着z坐标。比如 0 0 1 => z = 0*x + 0*y + 1*z
* 我们自己计算一个矩阵然后通过Matrax.setValues设置。
* 这样,在调用canvas的drawBitmap方法时,传入matrix
*
* Matrix类并不提倡我们使用这种方式来操作变换,Matrix针对不同的变换都相应的有pre,set,post三种方法
* 可以使用。
* pre是矩阵前乘
* set是直接设置
* post是矩阵后乘
*/
private Bitmap transferImage(){
Matrix matrix = new Matrix();
matrix.setValues(new float[]{ .5f,0,0,
//这里只会影响到x轴,所以,图片的长度将是原来的一半
0,1,0,
0,0,1
});
return this.getDstImage(matrix);
}
/**
* 该方法中我们将对图像的颜色,亮度,对比度等进行设置
* 需要用到ColorMatrix类。ColorMatrix类是一个四行五列的矩阵
* 每一行影响着[R,G,B,A]中的一个
* a1 b1 c1 d1 e1
* a2 b2 c2 d2 e2
* a3 b3 c3 d3 e3
* a4 b4 c4 d4 e4
* Rnew => a1*R+b1*G+c1*B+d1*A+e1
* Gnew => a2*R+b2*G+c2*B+d2*A+e2
* Bnew => a3*R+b3*G+c3*B+d3*A+e3
* Gnew => a4*R+b4*G+c4*B+d4*A+e4
* 其中R,G,B的值是128,A的值是0
*
* 最后将颜色的修改,通过Paint.setColorFilter应用到Paint对象中。
* 主要对于ColorMatrix,需要将其包装成ColorMatrixColorFilter对象,再传给Paint对象
*
* 同样的,ColorMatrix提供给我们相应的方法,setSaturation()就可以设置一个饱和度
*/
private Bitmap ajustImage(){
ColorMatrix cMatrix = new ColorMatrix();
// int brightIndex = -25;
// int doubleColor = 2;
// cMatrix.set(new float[]{
// doubleColor,0,0,0,brightIndex,
//这里将1改为2则我们让Red的值为原来的两倍
// 0,doubleColor,0,0,brightIndex,
//改变最后一列的值,我们可以不改变RGB同道颜色的基础上,改变亮度
// 0,0,doubleColor,0,brightIndex,
// 0,0,0,doubleColor,0
// });
//cMatrix.setSaturation(2.0f);//设置饱和度
cMatrix.setScale(2.0f, 2.0f, 2.0f, 2.0f);
//设置颜色同道色彩缩放
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));
return this.getDstImage(null, paint);
}
/**
* 图像的合成,可以通过在同一个Canvas中绘制两张图片。
* 只是在绘制第二章图片的时候,需要给Paint指定一个变幻模式TransferMode。
* 在Android中有一个XFermode所有的变幻模式都是这个类的子类
* 我们需要用到它的一个子类PorterDuffXfermode,关于这个类,其中用到PorterDuff类
* 这个类很简单,就包含一个Enum是Mode,其中定义了一组规则,这组规则就是如何将
* 一张图像和另一种图像进行合成
* 关于图像合成有四种模式,LIGHTEN,DRAKEN,MULTIPLY,SCREEN
*/
private Bitmap compositeImages(){
Bitmap bmp = null;
//下面这个Bitmap中创建的函数就可以创建一个空的Bitmap
bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Paint paint = new Paint();
Canvas canvas = new Canvas(bmp);
//首先绘制第一张图片,很简单,就是和方法中getDstImage一样
canvas.drawBitmap(srcBitmap, 0, 0, paint);
//在绘制第二张图片的时候,我们需要指定一个Xfermode
//这里采用Multiply模式,这个模式是将两张图片的对应的点的像素相乘
//,再除以255,然后以新的像素来重新绘制显示合成后的图像
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
canvas.drawBitmap(dstBitmap, 0, 0, paint);
return bmp;
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Log.v("Result OK Value:", resultCode+"");
Log.v("RequestCode Value", requestCode+"");
if(resultCode == RESULT_OK){
imageUri = data.getData();
if(requestCode == FIRST_PIC){
//在Gallery中选中一个图片时,返回来的Intent中的Data就是选择图片的Uri
srcBitmap = getSrcImage(imageUri);
srcImageView.setImageBitmap(srcBitmap);
}else if(requestCode == SECOND_PIC){
//这里处理用户选择的第二张图片
dstBitmap = getSrcImage(imageUri);
dstImageView.setImageBitmap(dstBitmap);
}
}
}
/**
* 需要加载的图片可能是大图,我们需要对其进行合适的缩小处理
* @param imageUri
*/
private Bitmap getSrcImage(Uri imageUri){
//Display display = this.getWindowManager().getDefaultDisplay();
try {
BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(imageUri),null,ops);
int wRatio = (int)Math.ceil(ops.outWidth/(float)MAX_WIDTH);
int hRatio = (int)Math.ceil(ops.outHeight/(float)MAX_HEIGHT);
if(wRatio > 1 && hRatio > 1){
if(wRatio > hRatio){
ops.inSampleSize = wRatio;
}else{
ops.inSampleSize = hRatio;
}
}
ops.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(imageUri),null,ops);
return bmp;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(this.getClass().getName(), e.getMessage());
}
return null;
}
}
分享到:
相关推荐
在.NET框架中,处理图像操作是一项常见的任务,包括图片上传、显示、编辑、剪切、旋转以及放大缩小等。这些功能广泛应用于各种Web应用程序和桌面应用程序中,如社交媒体平台、在线图像编辑工具和个人照片库应用。...
本节将深入探讨如何自动调整彩色图像的亮度、色度和饱和度,并通过编程实现这一功能。 首先,我们要了解亮度、色度和饱和度的概念。亮度是图像中最直观的属性,它决定了图像的整体明暗程度。亮度值越高,图像看起来...
总结来说,"BMP图像显示放大缩小"这一项目涵盖了基础的图像处理和用户交互功能,通过C++ MFC库,我们可以实现BMP文件的读取、图像的放大、缩小和平移,以及截图功能的扩展。这不仅锻炼了对图形接口的掌握,也提升了...
这个名为"图片放大、缩小、拖拽、旋转、全屏"的项目专注于提供一套完整的解决方案,使用户能够对图片进行一系列交互操作,包括但不限于缩放、移动、旋转以及全屏显示。这在网页设计、图像展示应用或任何需要用户互动...
下面我们将详细探讨C#中的偏移裁剪算法以及它如何应用于任意多边形。 首先,偏移裁剪算法的基本原理是将原始多边形的每个顶点按指定的距离向外或向内移动,形成一个新的多边形。这个过程通常涉及到处理顶点之间的...
在IT领域,尤其是在Windows应用程序开发中,经常需要处理图像显示和交互操作,如放大、缩小。本主题聚焦于使用C#编程语言中的PictureBox控件显示图片,并实现鼠标操作下的放大和缩小功能。同时,它也涉及到Halcon...
标题中的“大小图片放大缩小居中无偏移”意味着我们需要处理两个关键问题:图片的缩放操作以及在缩放过程中保持图片始终居中。这涉及到`UIScrollView`的几个重要属性和方法: 1. `contentSize`: 这个属性定义了`...
③根据四个顶点坐标,计算移动偏移量△x、△y,移动图像(目的使旋转后的图像全部能见); ④计算图像旋转后的坐标并填充对应原图像坐标的灰度值; ⑤显示旋转后的图像(可观察到图像中有许多空洞点),X轴标注为...
在C#编程环境中,开发图形用户界面(GUI)应用程序时,常常会涉及到图像处理操作,如图片的放大、缩小和移动。本示例基于C# 2005,使用PictureBox控件来实现这些功能。PictureBox是.NET Framework提供的一个强大控件...
在图像处理领域,图像放大、缩小和平移是基础且重要的操作。这些操作广泛应用于各种应用场景,如数字图像处理、计算机视觉、图像分析等。这里我们主要讨论的是使用C语言实现的图像变换源代码。 首先,图像放大是...
这个组件将支持图片的放大、缩小以及通过鼠标滚轮进行逐级缩放的功能。首先,我们需要理解Delphi的基础知识,它是基于Object Pascal的集成开发环境,提供了丰富的控件和库来构建桌面应用程序。 ### 1. Delphi控件...
`cropper.js` 是一个强大的 JavaScript 图片裁剪库,它支持在移动端和PC端进行图片的裁剪、放大、缩小和移动操作,极大地提高了用户体验。本教程将详细介绍如何利用 `cropper.js` 来实现这些功能。 首先,我们要...
这种方法的主要目的是在放大或缩小图像时,保持图像的视觉质量和细节尽可能地接近原始图像。双线性插值算法的基本思想是通过计算源图像中与目标像素位置相邻的4个像素的加权平均值来确定新像素的值。 在图像放大...
总的来说,"C#联合HALCON利用Halcon控件实现鼠标拖拽放大缩小图片"这个主题涵盖了C#的事件驱动编程、窗体控件操作以及HALCON图像处理库的应用。开发者需要理解C#的事件模型,熟悉HALCON的API接口,并具备一定的图形...
【Qt_图像放大缩小拖动功能.rar】是一个包含Qt源码的压缩包,主要用于实现图像在用户界面上的放大、缩小以及拖动操作。Qt是一个跨平台的C++图形用户界面应用程序开发框架,广泛用于桌面、移动和嵌入式系统的应用开发...
为了以图片中心为基准放大或缩小,我们需要在改变缩放比例之前先计算出当前鼠标位置相对于图片中心的偏移量,然后在缩放后恢复这个偏移,这样可以确保图片始终围绕鼠标位置进行缩放。 至于图片的移动,JavaFX提供了...
在IT行业中,实现类似地图放大缩小图片的功能是常见的图像处理技术,主要应用于地图应用、图像查看器、设计软件等。这种技术的核心在于图像的平移、缩放以及平滑处理,确保用户在查看高分辨率图像时能有良好的交互...
2. **旋转**:libyuv支持90度、180度、270度以及逆时针90度的旋转操作。例如,`I420Rotate`函数可以用于I420格式的YUV数据旋转,它会根据指定的旋转角度改变图像的方向。 3. **镜像**:libyuv也提供了水平或垂直...
本项目结合了MFC和Halcon,实现了通过鼠标操作对图像进行放大缩小和移动显示的功能,这在机器视觉应用或图像查看器等场景中非常实用。 首先,我们要理解MFC中的视图类(CView)和文档类(CDocument)。视图类是用户...