以前在实际项目中使用拍照和从图库中获取时,不知道以何种方式从回调中取得资源,以Bitmap方式还是Uri的形式?如果是使用Bitmap,应该注意些什么,Uri又是一种什么样的格式?有时会出现拍照时回调data数据为空的情况,又该如何定位问题呢?裁剪又是怎样决定方案的?以下将针对这几个问题阐述自己的见解。
在Android中,Intent触发 Camera程序,拍好照片后会返回数据,比如摄像头800万像素,拍出来的尺寸为 3200x2400,占据内存大小=3200 x 2400 x 4bytes / (1024 x 1024) = 30MB 图像设置ARGB_8888一个像素点占据4字节内存,这个尺寸对应的 Bitmap会耗光应用程序的内存,出于安全方面的考虑,Android会给你一个缩略图,比如 160 x 120 px。
Q:为何要返回图缩略?
缩略图是指从onActivityForResullt回调方法中 intent保存的参数。这是因为在启动相机程序拍摄,为了让Bitmap数据能在Activity之间传递,不得不将拍摄后的Bitmap进行压缩再传递,因此通过回调从intent中取得的是缩略图在于拍摄的Bitmap太大,Activity之间Bundle存放的数据不能太大,会导致程序无响应。高清原图是指直接将拍摄的以文件/Uri形式保存到手机。
注:Bitmap实现了Parcelable 接口,所有可以在Activity间使用Intent传递。
Q:使用Bitmap需要注意哪些问题?
1、Android 裁剪 Intent 附加数据的含义
| setExtra | DataType | Desciption | Extra |
|:-------- |:--------:| :------: |
|crop| String | Signals the crop feature | value="true" |
|aspectX|int|Aspect Ratio|裁剪横向比例|
|aspectY|int|Aspect Ratio|裁剪纵向比例|
|outputX|int|width od output created from this intent|输出宽度|
|outputY|int|height od output created from this intent|输出高度|
|scale|boolean|should it scale|是否伸缩|
|return-date|boolean|Return the bitmap with Action-inline-data by using the data|是否返回Bitmap数据|
|data|Parcelable|Bitmap to process, you may provide it a bitmap (not tested)|可设置data为Bitmap或者将相应数据同uri联系起来|
|circleCrop|String|if this string is not null, it will provide some cicular cr||
|MediaStore
EXTRA_OUTPUT("output")|URI|set this URI to a File|输出路径到uri中|
2、裁剪终极方案 — 来源有拍照和图库,可采取的 *** 作有:
3、剪切:
using System;
using SystemCollectionsGeneric;
using SystemText;
namespace SnhjCmsCommon
{
/// <summary>
/// 处理类
/// </summary>
public static class PictureUtil
{
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="imgPath">原路径</param>
/// <param name="breviaryPath">缩略图路径</param>
/// <param name="width">缩略图宽度</param>
/// <param name="height">缩略图高度</param>
/// <param name="mode">生成方式</param>
public static void MakeBreviaryPhoto(string imgPath, string breviaryPath, int width, int height, string mode)
{
SystemDrawingImage image = SystemDrawingImageFromFile(imgPath);
int x = 0, y = 0;
int w = imageWidth;
int h = imageHeight;
switch (mode)
{
case "HW"://指定高度和宽度缩放(会变形)
break;
case "W"://指定宽度缩放,高度按比例。
height = h width / w;
break;
case "H"://指定高度缩放,宽度按比例。
width = w height / h;
break;
case "Cut"://指定高度和宽度裁剪。
if ((double)w / (double)h > (double)width / (double)height)
{
w = h width / height;
x = (imageWidth - w) / 2;
}
else
{
h = w height / width;
y = (imageHeight - h) / 2;
}
break;
default:
break;
}
//创建一个bmp
SystemDrawingImage bmpImg = new SystemDrawingBitmap(width, height);
//新建一个画板
SystemDrawingGraphics g = SystemDrawingGraphicsFromImage(bmpImg);
//设置高质量插值法
gInterpolationMode = SystemDrawingDrawing2DInterpolationModeHigh;
//设置高质量,低速度呈现平滑程度
gSmoothingMode = SystemDrawingDrawing2DSmoothingModeHighQuality;
//清空画布并以透明背景色填充
gClear(SystemDrawingColorTransparent);
//在指定位置并且按指定大小绘制原的指定部分
gDrawImage(image, new SystemDrawingRectangle(0,0,width,height), new SystemDrawingRectangle(x,y,w,h), SystemDrawingGraphicsUnitPixel);
try
{
//以jpg格式保存缩略图
bmpImgSave(breviaryPath, SystemDrawingImagingImageFormatJpeg);
}
catch (Exception e)
{
throw e;
}
finally
{
imageDispose();
bmpImgDispose();
gDispose();
}
}
/// <summary>
/// 加水印
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="watermarkFilename">水印文件名</param>
/// <param name="watermarkStatus">水印位置:0=不使用 1=左上 2=中上 3=右上 4=左中 9=右下</param>
/// <param name="quality">是否是高质量 取值范围0--100</param>
/// <param name="watermarkTransparency">水印透明度 取值范围1--10 (10为不透明)</param>
public static void AddImageSignPic(string Path, string filename, string watermarkFilename, int watermarkStatus, int quality, int watermarkTransparency)
{
SystemDrawingImage img = SystemDrawingImageFromFile(Path);
SystemDrawingGraphics g = SystemDrawingGraphicsFromImage(img);
//设置高质量插值法
//gInterpolationMode = SystemDrawingDrawing2DInterpolationModeHigh;
//设置高质量,低速度呈现平滑程度
//gSmoothingMode = SystemDrawingDrawing2DSmoothingModeHighQuality;
SystemDrawingImage watermark = new SystemDrawingBitmap(watermarkFilename);
if (watermarkHeight >= imgHeight || watermarkWidth >= imgWidth)
{
return;
}
SystemDrawingImagingImageAttributes imageAttributes = new SystemDrawingImagingImageAttributes();
SystemDrawingImagingColorMap colorMap = new SystemDrawingImagingColorMap();
colorMapOldColor = SystemDrawingColorFromArgb(255, 0, 255, 0);
colorMapNewColor = SystemDrawingColorFromArgb(0, 0, 0, 0);
SystemDrawingImagingColorMap[] remapTable = { colorMap };
imageAttributesSetRemapTable(remapTable, SystemDrawingImagingColorAdjustTypeBitmap);
float transparency = 05F;
if (watermarkTransparency >= 1 && watermarkTransparency <= 10)
{
transparency = (watermarkTransparency / 100F);
}
float[][] colorMatrixElements = {
new float[] {10f, 00f, 00f, 00f, 00f},
new float[] {00f, 10f, 00f, 00f, 00f},
new float[] {00f, 00f, 10f, 00f, 00f},
new float[] {00f, 00f, 00f, transparency, 00f},
new float[] {00f, 00f, 00f, 00f, 10f}
};
SystemDrawingImagingColorMatrix colorMatrix = new SystemDrawingImagingColorMatrix(colorMatrixElements);
imageAttributesSetColorMatrix(colorMatrix, SystemDrawingImagingColorMatrixFlagDefault, SystemDrawingImagingColorAdjustTypeBitmap);
int xpos = 0;
int ypos = 0;
switch (watermarkStatus)
{
case 1:
xpos = (int)(imgWidth (float)01);
ypos = (int)(imgHeight (float)01);
break;
case 2:
xpos = (int)((imgWidth (float)50) - (watermarkWidth / 2));
ypos = (int)(imgHeight (float)01);
break;
case 3:
xpos = (int)((imgWidth (float)99) - (watermarkWidth));
ypos = (int)(imgHeight (float)01);
break;
case 4:
xpos = (int)(imgWidth (float)01);
ypos = (int)((imgHeight (float)50) - (watermarkHeight / 2));
break;
case 5:
xpos = (int)((imgWidth (float)50) - (watermarkWidth / 2));
ypos = (int)((imgHeight (float)50) - (watermarkHeight / 2));
break;
case 6:
xpos = (int)((imgWidth (float)99) - (watermarkWidth));
ypos = (int)((imgHeight (float)50) - (watermarkHeight / 2));
break;
case 7:
xpos = (int)(imgWidth (float)01);
ypos = (int)((imgHeight (float)99) - watermarkHeight);
break;
case 8:
xpos = (int)((imgWidth (float)50) - (watermarkWidth / 2));
ypos = (int)((imgHeight (float)99) - watermarkHeight);
break;
case 9:
xpos = (int)((imgWidth (float)99) - (watermarkWidth));
ypos = (int)((imgHeight (float)99) - watermarkHeight);
break;
}
gDrawImage(watermark, new SystemDrawingRectangle(xpos, ypos, watermarkWidth, watermarkHeight), 0, 0, watermarkWidth, watermarkHeight, SystemDrawingGraphicsUnitPixel, imageAttributes);
SystemDrawingImagingImageCodecInfo[] codecs = SystemDrawingImagingImageCodecInfoGetImageEncoders();
SystemDrawingImagingImageCodecInfo ici = null;
foreach (SystemDrawingImagingImageCodecInfo codec in codecs)
{
if (codecMimeTypeIndexOf("jpeg") > -1)
{
ici = codec;
}
}
SystemDrawingImagingEncoderParameters encoderParams = new SystemDrawingImagingEncoderParameters();
long[] qualityParam = new long[1];
if (quality < 0 || quality > 100)
{
quality = 80;
}
qualityParam[0] = quality;
SystemDrawingImagingEncoderParameter encoderParam = new SystemDrawingImagingEncoderParameter(SystemDrawingImagingEncoderQuality, qualityParam);
encoderParamsParam[0] = encoderParam;
if (ici != null)
{
imgSave(filename, ici, encoderParams);
}
else
{
imgSave(filename);
}
gDispose();
imgDispose();
watermarkDispose();
imageAttributesDispose();
}
/// <summary>
/// 在上生成水印
/// </summary>
/// <param name="Path">原服务器路径</param>
/// <param name="Path_syp">生成的带水印的路径</param>
/// <param name="Path_sypf">水印路径</param>
public static void AddWaterPic(string Path, string Path_syp, string Path_sypf)
{
SystemDrawingImage image = SystemDrawingImageFromFile(Path);
SystemDrawingImage copyImage = SystemDrawingImageFromFile(Path_sypf);
SystemDrawingGraphics g = SystemDrawingGraphicsFromImage(image);
gDrawImage(copyImage, new SystemDrawingRectangle(imageWidth - copyImageWidth, imageHeight - copyImageHeight, copyImageWidth, copyImageHeight), 0, 0, copyImageWidth, copyImageHeight, SystemDrawingGraphicsUnitPixel);
gDispose();
imageSave(Path_syp);
imageDispose();
}
}
}
1加载出来的变绿
2加载出来的和实际显示有区别,背景层次更深。
自定义一个全局的 GlideModule
在AndroidManifestxml中加入:
Glidewith(context)load(url)asBitmap()format(PREFER_ARGB_8888)
给你一个java的,自己改改
import javaawt;
import javaawtimage;
import javautilRandom;
import javaio;
import javaxswing;
public class LoadImage {
/
@param args
/
public static void main(String[] args) {
String myreadline = "";
//定义一个String类型的变量,用来每次读取一行
try {
FileReader fr = new FileReader("data/imagelisttxt");//创建FileReader对象,用来读取字符流
BufferedReader br = new BufferedReader(fr); //缓冲指定文件的输入
FileWriter fw = new FileWriter("data/17d_resulttxt");//创建FileWriter对象,用来写入字符流
BufferedWriter bw = new BufferedWriter(fw); //将缓冲对文件的输出
while (brready()) {
myreadline = brreadLine();//读取一行
BufferedImage image = toBufferedImage(new ImageIcon("data/Image/"+myreadline)getImage());
int height = imagegetHeight();
int width = imagegetWidth();
int r1=0, r2=0, r3=0, r4=0, r5=0, r6=0, r7=0, r8=0, r9=0, r10=0, r11=0, r12=0, r13=0, r14=0, r15=0, r16=0, r17=0;
int g1=0, g2=0, g3=0, g4=0, g5=0, g6=0, g7=0, g8=0, g9=0, g10=0, g11=0, g12=0, g13=0, g14=0, g15=0, g16=0, g17=0;
int b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0, b8=0, b9=0, b10=0, b11=0, b12=0, b13=0, b14=0, b15=0, b16=0, b17=0;
int rgb1=0, rgb2=0, rgb3=0, rgb4=0, rgb5=0, rgb6=0, rgb7=0, rgb8=0, rgb9=0, rgb10=0, rgb11=0, rgb12=0, rgb13=0, rgb14=0, rgb15=0, rgb16=0, rgb17=0;
//Systemoutprintln("Height=" + height + ", Width=" + width);
//Random ran = new Random();
//int x = rannextInt(width), y = rannextInt(height);
for (int y=0;y<height;y++) {
for (int x=0;x<width;x++) {
Color color = new Color(imagegetRGB(x, y));
if(colorgetRed()<=15)
r1++;
if(colorgetRed()>15 && colorgetRed()<=30)
r2++;
if(colorgetRed()>30 && colorgetRed()<=45)
r3++;
if(colorgetRed()>45 && colorgetRed()<=60)
r4++;
if(colorgetRed()>60 && colorgetRed()<=75)
r5++;
if(colorgetRed()>75 && colorgetRed()<=90)
r6++;
if(colorgetRed()>90 && colorgetRed()<=105)
r7++;
if(colorgetRed()>105 && colorgetRed()<=120)
r8++;
if(colorgetRed()>120 && colorgetRed()<=135)
r9++;
if(colorgetRed()>135 && colorgetRed()<=150)
r10++;
if(colorgetRed()>150 && colorgetRed()<=165)
r11++;
if(colorgetRed()>165 && colorgetRed()<=180)
r12++;
if(colorgetRed()>180 && colorgetRed()<=195)
r13++;
if(colorgetRed()>195 && colorgetRed()<=210)
r14++;
if(colorgetRed()>210 && colorgetRed()<=225)
r15++;
if(colorgetRed()>225 && colorgetRed()<=240)
r16++;
if(colorgetRed()>240 && colorgetRed()<=255)
r17++;
if(colorgetGreen()<=15)
g1++;
if(colorgetGreen()>15 && colorgetGreen()<=30)
g2++;
if(colorgetGreen()>30 && colorgetGreen()<=45)
g3++;
if(colorgetGreen()>45 && colorgetGreen()<=60)
g4++;
if(colorgetGreen()>60 && colorgetGreen()<=75)
g5++;
if(colorgetGreen()>75 && colorgetGreen()<=90)
g6++;
if(colorgetGreen()>90 && colorgetGreen()<=105)
g7++;
if(colorgetGreen()>105 && colorgetGreen()<=120)
g8++;
if(colorgetGreen()>120 && colorgetGreen()<=135)
g9++;
if(colorgetGreen()>135 && colorgetGreen()<=150)
g10++;
if(colorgetGreen()>150 && colorgetGreen()<=165)
g11++;
if(colorgetGreen()>165 && colorgetGreen()<=180)
g12++;
if(colorgetGreen()>180 && colorgetGreen()<=195)
g13++;
if(colorgetGreen()>195 && colorgetGreen()<=210)
g14++;
if(colorgetGreen()>210 && colorgetGreen()<=225)
g15++;
if(colorgetGreen()>225 && colorgetGreen()<=240)
g16++;
if(colorgetGreen()>240 && colorgetGreen()<=255)
g17++;
if(colorgetBlue()<=15)
b1++;
if(colorgetBlue()>15 && colorgetBlue()<=30)
b2++;
if(colorgetBlue()>30 && colorgetBlue()<=45)
b3++;
if(colorgetBlue()>45 && colorgetBlue()<=60)
b4++;
if(colorgetBlue()>60 && colorgetBlue()<=75)
b5++;
if(colorgetBlue()>75 && colorgetBlue()<=90)
b6++;
if(colorgetBlue()>90 && colorgetBlue()<=105)
b7++;
if(colorgetBlue()>105 && colorgetBlue()<=120)
b8++;
if(colorgetBlue()>120 && colorgetBlue()<=135)
b9++;
if(colorgetBlue()>135 && colorgetBlue()<=150)
b10++;
if(colorgetBlue()>150 && colorgetBlue()<=165)
b11++;
if(colorgetBlue()>165 && colorgetBlue()<=180)
b12++;
if(colorgetBlue()>180 && colorgetBlue()<=195)
b13++;
if(colorgetBlue()>195 && colorgetBlue()<=210)
b14++;
if(colorgetBlue()>210 && colorgetBlue()<=225)
b15++;
if(colorgetBlue()>225 && colorgetBlue()<=240)
b16++;
if(colorgetBlue()>240 && colorgetBlue()<=255)
b17++;
}
}
rgb1 = r1 + g1 + b1;
rgb2 = r2 + g2 + b2;
rgb3 = r3 + g3 + b3;
rgb4 = r4 + g4 + b4;
rgb5 = r5 + g5 + b5;
rgb6 = r6 + g6 + b6;
rgb7 = r7 + g7 + b7;
rgb8 = r8 + g8 + b8;
rgb9 = r9 + g9 + b9;
rgb10 = r10 + g10 + b10;
rgb11 = r11 + g11 + b11;
rgb12 = r12 + g12 + b12;
rgb13 = r13 + g13 + b13;
rgb14 = r14 + g14 + b14;
rgb15 = r15 + g15 + b15;
rgb16 = r16 + g16 + b16;
rgb17 = r17 + g17 + b17;
//Systemoutprintln("rect " + rgb1 + " " + rgb2 + " " + rgb3);
bwwrite("rect " + rgb1 + " " + rgb2 + " " + rgb3 + " " + rgb4 + " " + rgb5 + " " + rgb6 + " " + rgb7 + " " + rgb8 + " " + rgb9 + " " + rgb10 + " " + rgb11 + " " + rgb12 + " " + rgb13 + " " + rgb14 + " " + rgb15 + " " + rgb16 + " " + rgb17); //写入文件
bwnewLine();
//Systemoutprintln(myreadline);//在屏幕上输出
}
bwflush(); //刷新该流的缓冲
bwclose();
brclose();
fwclose();
brclose();
frclose();
} catch (IOException e) {
eprintStackTrace();
}
}
// This method returns a buffered image with the contents of an image
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// Determine if the image has transparent pixels; for this method's
// implementation, see e661 Determining If an Image Has Transparent
// Pixels
boolean hasAlpha = hasAlpha(image);
// Create a buffered image with a format that's compatible with the
// screen
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment
getLocalGraphicsEnvironment();
try {
// Determine the type of transparency of the new buffered image
int transparency = TransparencyOPAQUE;
if (hasAlpha) {
transparency = TransparencyBITMASK;
}
// Create the buffered image
GraphicsDevice gs = gegetDefaultScreenDevice();
GraphicsConfiguration gc = gsgetDefaultConfiguration();
bimage = gccreateCompatibleImage(imagegetWidth(null), image
getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImageTYPE_INT_RGB;
if (hasAlpha) {
type = BufferedImageTYPE_INT_ARGB;
}
bimage = new BufferedImage(imagegetWidth(null), image
getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimagecreateGraphics();
// Paint the image onto the buffered image
gdrawImage(image, 0, 0, null);
gdispose();
return bimage;
}
// This method returns true if the specified image has transparent pixels
public static boolean hasAlpha(Image image) {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage) image;
return bimagegetColorModel()hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pggrabPixels();
} catch (InterruptedException e) {
}
// Get the image's color model
ColorModel cm = pggetColorModel();
return cmhasAlpha();
}
}
/// <summary>
/// 获取指定透明度的图像
/// </summary>
/// <param name="SourceBitmap">源图像</param>
/// <param name="OpaCityValue">透明度百分比</param>
/// <returns></returns>
/// <remarks></remarks>
public Bitmap TheTransparentBitmap(Bitmap SourceBitmap, double OpaCityValue)
{
try {
//定义临时副本
Bitmap ForOutBitmap = new Bitmap(SourceBitmap);
//定义图像数据
BitmapData bmpDATA = new BitmapData();
//将图像指定区域数据赋值
bmpDATA = ForOutBitmapLockBits(new Rectangle(0, 0, SourceBitmapWidth - 1, SourceBitmapHeight - 1), ImageLockModeReadOnly, PixelFormatFormat32bppArgb);
//定义用来计算的Byte数组
byte[] BTS = new byte[bmpDATAStride bmpDATAHeight + 1];
//将Byte设置为指定的图像数据
SystemRuntimeInteropServicesMarshalCopy(bmpDATAScan0, BTS, 0, BTSLength - 1);
//为避免"除数不可为0"而设置的计算用变量
int tmpValue = 0;
//因已经指定为32位ARGB模式,所以每4个排列为 B G R A,A即透明度
for (int I = 0; I <= BTSLength - 4; I += 4) {
tmpValue = BTS[I + 3] OpaCityValue;
//修改A透明度
BTS[I + 3] = tmpValue;
}
//完成计算后将Byte组返回给指定的图像数据
SystemRuntimeInteropServicesMarshalCopy(BTS, 0, bmpDATAScan0, BTSLength - 1);
//解锁该图像数据以使调用线程继续执行
ForOutBitmapUnlockBits(bmpDATA);
//返回处理后的图像
return ForOutBitmap;
} catch (Exception ex) {
//如出现异常则返回空值
return null;
}
}
软糖花了好长时间才弄好,主要是Color之间不能直接比较,要先转化ToArgb()。
坐标从 矩形集合[n]X ,矩形集合[n]Y 中获取。
如果有重叠部分,可能会不准确,有时候多一块,未能排除此BUG
窗体上有两个控件 picturebox1,位于顶部 width = 900 height= 100
button1有个click事件用来演示搜索。
上代码
public partial class Form1 : Form{
public Form1()
{
InitializeComponent();
}
int 色块宽=10;
int 色块高=10;
Random rnd = new Random();
Color black = ColorBlack;
Brush brush;
Bitmap 图像;
List<Rectangle> 矩形集合 = new List<Rectangle>();
private void 搜索色块()
{
int ARGB值 = blackToArgb();
for (int x = 0; x < 900; x++)
{
for (int y = 0; y < 100; y++)
{
bool b = false;
//如果坐标X,Y不在任何集合中的矩形范围内,在进行判断
foreach (var rect in 矩形集合)
{
if (rectContains(x, y)) { b = true; }
}
if (b == false)
{
//取色,并转化为ARGB值比较,如果是黑色,就把这个矩形加入列表
//Color比较还要比对颜色名称,即使ARGB分量完全相同,颜色名称不同比较结果也是不等。
if (图像GetPixel(x, y)ToArgb() == ARGB值)
{ 矩形集合Add(new Rectangle(x, y, 色块宽+1, 色块高+1)); }
}
}
}
//遍历矩形集合,获取坐标: 矩形集合[n]Location
button1Text = stringFormat("{0}",矩形集合Count);
}
private void 绘制色块()
{
图像 = new Bitmap(900, 100);
brush = new SolidBrush(black);
Graphics g = GraphicsFromImage(图像);
for (int i = 1; i <= 19; i++)
{
int x = rndNext(1, 900 - 色块宽);
int y = rndNext(1, 100 - 色块高);
gFillRectangle(brush, x, y, 色块宽, 色块高);
}
}
private void Form1_Click(object sender, EventArgs e)
{
绘制色块();
pictureBox1Image = 图像;
}
private void button1_Click(object sender, EventArgs e)
{
搜索色块();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
如满意,请采纳,谢谢。
Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等 *** 作,并可以指定格式保存图像文件。本文从应用的角度,着重介绍怎么用Bitmap来实现这些功能。
一、Bitmap的生成
11 BitmapFactory decode出Bitmap
Bitmap实现在androidgraphics包中。但是Bitmap类的构造函数是私有的,外面并不能实例化,只能是通过JNI实例化。这必然是 某个辅助类提供了创建Bitmap的接口,而这个类的实现通过JNI接口来实例化Bitmap的,这个类就是BitmapFactory。
图一、BitmapFactory主要方法及Options选项
利用BitmapFactory可以从一个指定文件中,利用decodeFile()解出Bitmap;也可以定义的资源中,利用decodeResource()解出Bitmap。
12 decode时的选项
在使用方法decodeFile()/decodeResource()时,都可以指定一个BitmapFacotryOptions。
利用Options的下列属性,可以指定decode的选项:
inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在BitmapConfig中。缺省值是ARGB_8888。
inJustDecodeBounds 如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息。
inSampleSize 设置decode时的缩放比例。
利用Options的这些值就可以高效的得到一幅缩略图。
图二、BitmapFactorydecodeFile()
先设置inJustDecodeBounds= true,调用decodeFile()得到图像的基本信息[Step#2~4];
利用图像的宽度(或者高度,或综合)以及目标的宽度,得到inSampleSize值,再设置inJustDecodeBounds= false,调用decodeFile()得到完整的图像数据[Step#5~8]。
先获取比例,再读入数据,如果欲读入大比例缩小的图,将显著的节约内容资源。有时候还会读入大量的缩略图,这效果就更明显了。
二、利用Bitmap和Matrix实现图像变换
Bitmap可以和Matrix结合实现图像的剪切、旋转、缩放等 *** 作。
图三、Bitmap方法
用源Bitmap通过变换生成新的Bitmap的方法:
public static Bitmap createBitmap(Bitmap source, int x, int y, intwidth, int height,
Matrix m, boolean filter)
public static Bitmap createBitmap(Bitmap source, int x, int y, intwidth, int height)
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth,
int dstHeight,boolean filter)
第一个方法是最终的实现,后两种只是对第一种方法的封装。
第二个方法可以从源Bitmap中指定区域(x,y, width, height)中挖出一块来实现剪切;第三个方法可以把源Bitmap缩放为dstWidth x dstHeight的Bitmap。
设置Matrix的Rotate(通过setRotate())或者Scale(通过setScale()),传入第一个方法,可实现旋转或缩放。
图四、Bitmap实现旋转
三、保存图像文件
经过图像变换之后的Bitmap里的数据可以保存到图像压缩文件里(JPG/PNG)。
图五、保存Bitmap数据到文件
这个 *** 作过程中,Bitmapcompress()方法的参数format可设置JPEG或PNG格式;quality可选择压缩质量;fOut是输出流(OutputStream),这里的FileOutputStream是OutputStream的一个子类。
总结一下,本文介绍Bitmap的使用方法——用Bitmap实现图像文件的读取和写入,并用Bitmap实现图像的剪切、旋转和缩放变换。
以上就是关于Android拍照、从图库导入以及图片裁剪全部的内容,包括:Android拍照、从图库导入以及图片裁剪、如何通过c#读写图片(JPG格式)的摘要信息、Glide单独设置ARGB_8888等图片质量等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)