bitmap保存到本地(如何将本地图片保存到相册)
本文目录
- 如何将本地图片保存到相册
- 安卓从手机相册获取照片作为头像缓存地址
- Android 保存图片到本地
- 请问AS3.0 怎样可以将Bitmap对象保存为本地图片文件(如JPG文件)谢谢!
- android bitmap 改变图片大小
- 如何将Bitmap保存为本地图片文件
- android中人脸识别扫描人然后怎样将图像保存到本地数据库
- asp.net中服务器上的bitmap对象怎样保存到本地文件
如何将本地图片保存到相册
我们都知道将图片保存到本地的操作,但是如何将本地的图片保存到相册。有几种不同的方法,下面分别讲述这几种方法。 上面两种方法是调用了系统的方法,将图片的bitmap对象或者图片的路径作为参数传递,但是仅仅是这样调用还是不能在相册中看到图片。 我们还需要更新图片库,使用下面的方法可以更新图片库: 上面的方法是扫描图片路径并将该图片显示到相册中。 可以说上面的方法以及能够满足大部分手机的显示图片的需求,但是在另外一些手机,比如华为、OPPO,就存在兼容性问题。它会将图片显示在相册的最前面。所以当手机相册很多时,我们会产生这张图片没有被插入到相册的错觉。 那为什么会发生上面的情况呢?首先我们查看一下被插入的图片的详情: 可以看到图片被插入到了最前面(图片下标为1/304),再看图片详情,时间居然是1970/1/1 08:00:00,我们知道相册中的图片都是按照时间的顺序升序的,所以怪不得图片会被插入到最前面。 下面我们再来看为什么时间会是1970/1/1 08:00:00。这个我们从源码中入手找原因,直接进入MediaStore.Images.Media.insertImage()方法: 通过上面的源码可知,图片是通过contentProvider插入的,调用的是ContentResolver的insert方法,其中第二个参数是ContentValues对象,它包含了图片的信息。比如上面就仅仅包含了图片的标题、描述、图片类型。我们看到上面仅仅put进去了三个键值对,而每一个key都是MediaColumns接口的常量,我们再来看一下还有哪些常量,对于图片来说,可以看到还有DATE_TAKEN这个常量,再来看一下它的注释: 这个参数表示我们的图片是什么时候拍摄的,这个时间是以毫秒为单位的,并且时间基点是1970年1月1日,这个时间看起来是不是很熟悉,我们上面那张图片详情的时间也是1970年1月1日。 那么我们是不是可以认为调用MediaStore.Images.Media.insertImage()方法时,默认将时间设置为1970年1月1日,因此会将图片显示在相册的最前面。 知道了原因了之后,那么我们就仿照MediaStore.Images.Media.insertImage()自己写一个方法进行图片的插入,并且将图片的拍摄时间写进去,不就可以解决那个问题了吗?具体的方法如下所示: 使用了上面的方法后,图片可以成功地保存在系统相册中,并且能够正确显示在相册的最后面。而且我们还创建了一个属于我们自己的相册文件夹”myPhotos",我们可以将自己的应用的所有图片都保存在自己相册文件夹中。
安卓从手机相册获取照片作为头像缓存地址
* 1、实现原理:用户打开相册或相机选择相片后,相片经过压缩并设置在控件上,图片在本地sd卡存一份(如果有的话,没有则内部存储,所以还 * 需要判断用户是否挂载了sd卡),然后在服务器上存储一份该图片,当下次再次启动应用时,会默认去sd卡加载该图片,如果本地没有,再会去联网请求 * 2、使用了picasso框架以及自定义BitmapUtils工具类 * 3、记得加上相关权限 * 《uses-permission android:name="android.permission.INTERNET"》《/uses-permission》 《uses-permission android:name="android.permission.CAMERA"/》 《uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"》《/uses-permission》 * */public class MainActivity extends AppCompatActivity implements View.OnClickListener { private ImageView iv;//要设置的头像 private Button btn_photo;//调用相册按钮 private Button btn_camera;//调用相机按钮 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv=(ImageView) findViewById(R.id.iv); btn_photo = (Button) findViewById(R.id.btn_photo); btn_camera = (Button) findViewById(R.id.btn_camera); btn_photo.setOnClickListener(this); btn_camera.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_photo://打开系统相册 Intent intent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent,100); break; case R.id.btn_camera://打开系统相机 Intent intent2=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent2,200); break; } } @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==100&&resultCode==RESULT_OK&&data!=null){//系统相册 Uri imageData = data.getData(); String path=getPath(imageData); Bitmap bitmap = BitmapFactory.decodeFile(path); Bitmap bitmap1 = BitmapUtils.zoom(bitmap, iv.getWidth(), iv.getHeight()); Bitmap bitmap2 = BitmapUtils.circleBitmap(bitmap1); //加载显示 iv.setImageBitmap(bitmap2); //bitmap图片上传到服务器...... //bitmap图片保存到本地 saveImage(bitmap2); }else if(requestCode==200&&resultCode==RESULT_OK&&data!=null){//系统相机 Bitmap bitmap = (Bitmap) data.getExtras().get("data"); BitmapUtils.zoom(bitmap,iv.getWidth(),iv.getHeight()); bitmap=BitmapUtils.circleBitmap(bitmap); //加载显示 iv.setImageBitmap(bitmap); //bitmap图片上传到服务器...... //bitmap图片保存到本地 saveImage(bitmap); } } /** * 数据的存储。(5种) * Bimap:内存层面的图片对象。 * * 存储---》内存: * BitmapFactory.decodeFile(String filePath); * BitmapFactory.decodeStream(InputStream is); * 内存---》存储: * bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os); */ private void saveImage(Bitmap bitmap) { File filesDir; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断sd卡是否挂载 //路径1:storage/sdcard/Android/data/包名/files filesDir = this.getExternalFilesDir(""); }else{//手机内部存储 //路径:data/data/包名/files filesDir = this.getFilesDir(); } FileOutputStream fos = null; try { File file = new File(filesDir,"icon.png"); fos = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100,fos); } catch (FileNotFoundException e) { e.printStackTrace(); }finally{ if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } //如果本地有,就不需要再去联网去请求 private boolean readImage() { File filesDir; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断sd卡是否挂载 //路径1:storage/sdcard/Android/data/包名/files filesDir = getExternalFilesDir(""); }else{//手机内部存储 //路径:data/data/包名/files filesDir = getFilesDir(); } File file = new File(filesDir,"icon.png"); if(file.exists()){ //存储---》内存 Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); iv.setImageBitmap(bitmap); return true; } return false; } @RequiresApi(api = Build.VERSION_CODES.KITKAT) private String getPath(Uri uri) { int sdkVersion = Build.VERSION.SDK_INT; //高于4.4.2的版本 if (sdkVersion 》= 19) { Log.e("TAG", "uri auth: " + uri.getAuthority()); if (isExternalStorageDocument(uri)) { String docId = DocumentsContract.getDocumentId(uri); String split = docId.split(":"); String type = split; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split; } } else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(this, contentUri, null, null); } else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String split = docId.split(":"); final String type = split; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String}; return getDataColumn(this, contentUri, selection, selectionArgs); } else if (isMedia(uri)) { String proj = {MediaStore.Images.Media.DATA}; Cursor actualimagecursor = this.managedQuery(uri, proj, null, null, null); int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); actualimagecursor.moveToFirst(); return actualimagecursor.getString(actual_image_column_index); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(this, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * uri路径查询字段 * * @param context * @param uri * @param selection * @param selectionArgs * @return */ public static String getDataColumn(Context context, Uri uri, String selection, String selectionArgs) { Cursor cursor = null; final String column = "_data"; final String projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } private boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } public static boolean isMedia(Uri uri) { return "media".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } /** * 判断本地是否有该图片,没有则去联网请求 * */ @Override protected void onResume() { super.onResume(); if(readImage()){ return; } }}//BitmapUtils工具类public class BitmapUtils { /** * 该方法用于将图片进行圆形处理 * */ public static Bitmap circleBitmap(Bitmap source){ //默认只对宽进行处理 int width=source.getWidth(); Bitmap bitmap=Bitmap.createBitmap(width,width,Bitmap.Config.ARGB_8888); Canvas canvas=new Canvas(bitmap); Paint paint=new Paint(); //设置抗锯齿 paint.setAntiAlias(true); canvas.drawCircle(width/2,width/2,width/2,paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(source,0,0,paint); return bitmap; } /** * 该方法用于图片压缩处理,注意width、height参数的类型必须是float * */ public static Bitmap zoom(Bitmap source,float width,float height){ Matrix matrix=new Matrix(); //图片进行压缩处理 matrix.postScale(width/source.getWidth(),height/source.getHeight()); Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, false); return bitmap; }}以上所述是小编给大家介绍的Android实现调用系统图库与相机设置头像并保存在本地及服务器 ,希望对大家有所帮助
Android 保存图片到本地
这里只介绍按下“保存”后如何将一个Bitmap对象保存为图片文件的执行步骤,对图片的下载,图片到Bitmap对象的转换,Bitmap对象的格式转换和压缩,以及界面设计部分全部都忽略了。
确定存储路径
获取外部存储权限
确定外部存储状态
确定文件名
保存到文件中
发送广播,通知系统扫描保存后的文件
String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tencent/MicroMsg/WeiXin/"
《uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/》
//获取内部存储状态
String state = Environment.getExternalStorageState();
//如果状态不是mounted,无法读写
if (!state.equals(Environment.MEDIA_MOUNTED)) {
return;
}
随机命名这种命名规则是随机生成一个字符串或一组数字来对图片命名。字符串可以通过UUID来生成,数字可以通过Random()类来生成,例如:
view plain copy
//通过UUID生成字符串文件名
String fileName1 = UUID.randomUUID().toString();
//通过Random()类生成数组命名
Random random = new Random();
String fileName2 = String.valueOf(random.nextInt(Integer.MAX_VALUE));
这种命名规则是按照数字从小到大的顺序来对图片命名。在程序启动时先获取图片文件名中当前最大数字的文件名,之后每保存一张图片就将数字加1即可。
时间命名这种命名规则是根据保存图片的当前系统时间来对图片命名。系统时间可以通过System.currentTimeMillis()来获取,不过System.currentTimeMillis()获取到的时间是一个long型的整数,如果用它做文件名,无法通过文件名直接看出文件的具体保存时间。可以通过SimpleDateFormat先对当前时间做格式化,然后再将其作为文件名来使用。例如:
view plain copy
使用这种命名规则来命名需要注意的是同一秒钟可能会有多张图片需要保存,在得到当前系统时间对应的文件名后,需要判断该文件是否存在。如果文件已经存在,需要重新生成文件名。重新生成的文件名可以在之前的文件名后加上一个随机数后缀,或者是用毫秒数做后缀。
Calendar now = new GregorianCalendar();
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
String fileName = simpleDate.format(now.getTime());
文件URL命名每张网络图片都有一个对应的图片URL,可以根据图片的URL来对图片命名。不过URL中会包含一些不能用作文件名的特殊字符,此外直接用URL来命名可能会带来安全问题。为了避免这两个问题,可以将图片URL的MD5值作为文件名来使用。由于MD5是不可逆的,也就无法通过MD5值反向得到图片URL,同时MD5值对应的字符串只包含,不包含特殊字符,可是作为文件名使用。由于每张图片的URL是唯一的,其对应的文件名也就是唯一的。如果需要每张网络图片只能生成一个文件,不允许保存为多份拷贝,可以用这种命名规则。在得到URL对应的文件名后,先判断文件是否已经存在,如果已经存在,直接覆盖或不处理。
try {
File file = new File(dir + fileName + ".jpg");
FileOutputStream out = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
File file = new File(dir + fileName + ".jpg");
FileOutputStream out = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
//保存图片后发送广播通知更新数据库
Uri uri = Uri.fromFile(file);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
} catch (Exception e) {
e.printStackTrace();
}
确定存储路径
在Android中文件存储路径包括内部存储和外部存储两种类型。
对内部存储,当一个app被安装到手机后,Android系统会在内部存储的/data/data/目录下创建一个以包名称命名的文件夹。例如/data/data/com.sohu.inputmethod.sogou/。一个应用对内部存储的所有访问都被限制在这个文件夹中,也就是说Android应用只能在该目录中读取,创建,修改文件。对该目录之外的其他内部存储中的目录都没有任何操作的权限。因此,如果将图片保存在内部存储中,只能被应用自身读取,其他应用均无法读取。如果需要让系统图库,相册或其他应用能够找到保存的图片,必须将图片保存到外部存储中。
对外部存储,当一个app被安装到手机后,Android系统会在外部存储的/Android/data/目录下创建一个以包名命名的文件夹(这里第一个/不是根路径,而是相对外部存储所挂载路径的相对路径)。例如/storage/emulated/0/Android/data/com.sohu.inputmethod/。这个路径同样只能被应用自身读取,其他应用不能访问。因此,也不能将图片保存在这个目录中。
除外部存储的/Android目录之外的其他目录一般都是可以被其他应用访问的。目前,大多数应用都会在外部存储的根路径下建立一个类似包名的多层目录,以存储需要共享的文件。例如/storage/emulated/0/sogou/image/。还需要注意的是,很多查看图片的应用都支持按照文件夹来查看图片。如果将图片所在的文件夹取名为image,photo之类的,就无法和其他文件夹区分开,用户也不能识别该文件夹的用途。因此最好取一个有区分度的文件夹名字,例如百度贴吧就保存在/tieba目录,微信是保存在/tencent/MicroMsg/WeiXin目录。
由于Android系统的碎片化问题,不同设备上外部存储的路径很可能会不同,因此,不能直接使用/storage/emulated/0/作为外部存储的根路径。Android SDK中 Environment类 提供了getExternalStorageDirectory()方法来获取外部存储的根路径。示例如下:
view plain copy
需要注意的是Environment.getExternalStorageDirectory()返回的路径中最后一个字符不是/,如果需要创建子目录,需要在子目录的前后都加上/。
获取外部存储权限
由于需要在外部存储中写文件,需要在AndroidManifest.xml中增加如下的权限声明。
view plain copy
确定外部存储状态
由于外部存储需要被挂载,也可以被卸载,在写入文件之前,需要先判断外部存储的状态是否正常。只有状态正常情况下才可以执行保存文件的操作。获取外部存储状态同样是通过Environment类,通过Environment.getExternalStorageState()可以得到一个字符串,来表示外部存储的状态。同时在Environment类中定义了一系列的String常量表示不同的状态。在所有的状态中只有内部存储处于Environment.MEDIA_MOUNTED状态时才可以读写文件,因此,需要将获取到的状态和Environment.MEDIA_MOUNTED做比较,如果不是Environment.MEDIA_MOUNTED状态,就返回保存失败。示例如下。
view plain copy
确定文件名
保存的图片文件名可以由应用根据自身需要自行确定,一般来说需要有一个命名规则,然后根据命名规则计算得到文件名。这里列举几种常见的命名规则。
保存到文件中
保存图片文件时,通过Bitmap的compress()方法将Bitmap对象压缩到一个文件输出流中,然后flush()即可。示例如下。
view plain copy
发送广播,通知系统扫描保存后的文件
至此,已经实现将Bitmap对象保存成外部存储中的一个jpg格式的文件。但此时该文件只是保存在外部存储的一个目录中,必须进入其所在的目录中才可以看到。在系统图库,相册和其他应用中无法看到新建的图片文件。为了让其他应用能够知道图片文件被创建,必须通知MediaProvider服务将新建的文件添加到图片数据库中。
Android系统中常驻一个MediaProvider服务,对应的进程名为android.process.media,此服务用来管理本机上的媒体文件,提供媒体管理服务。在系统开机或者收到外部存储的挂载消息后,MediaProvider会调用MediaScanner,MediaScanner会扫描外部存储中的所有文件,根据文件类型的后缀将文件信息保存到对应的数据库中,供其他APP使用。
MediaScannerReceiver是一个广播接收者,当它接收到特定的广播请求后,就会去扫描指定的文件,并根据文件信息将其添加到数据库中。当图片文件被创建后,就可以发送广播给MediaScannerReceiver,通知其扫描新建的图片文件。示例如下。
view plain copy
图片的异步保存
保存图片文件时,如果图片很大,或需要同时保存多张图片时,就需要较多的时间。为了避免阻塞UI线程,出现帧率下降或ANR,通常需要将图片保存操作放到线程中去执行。当图片保存完毕后通过sendMessage()方法通知UI线程保存结果。将图片保存放到后台线程去执行需要增加一些同步机制避免一些多线程问题。例如有两张图片需要保存,分别放到两个线程中去执行,保存图片时文件名以数字顺序增加。第一个线程选中文件名为125.jpg,但此时文件还未创建,第二个线程判断125.jpg不存在,于是也选取125.jpg作为文件名,两张图片就保存到同一个文件中了。
请问AS3.0 怎样可以将Bitmap对象保存为本地图片文件(如JPG文件)谢谢!
在FLASH PLAYER10之前比较麻烦但现在依靠FP10简单实现在FLASH CS4↑版本,若要导出图片,可以这样写var file:FileReference = new FileReference();file.save(要保存的数据,"保存的文件名"); (如file.save("test", "test.txt"),然后保存在桌面保存完成后会在桌面看到一个内容为test的文本)然后会弹出WINODWS的保存窗口,选择路径,保存完成~
android bitmap 改变图片大小
Options options1 = new Options(); options1.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options1); options1.inSampleSize = RegisterTool.calculateInSampleSize(options1, 110, 160); //110,160:转换后的宽和高,具体值会有些出入 options1.inJustDecodeBounds = false; Bitmap bitmap = BitmapFactory.decodeFile(filePath, options1); //filePath:文件路径
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height 》 reqHeight || width 》 reqWidth) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio 《 widthRatio ? widthRatio : heightRatio; } return inSampleSize; }
//压缩图片并将Bitmap保存到本地 FileOutputStream out = new FileOutputStream(new File(filePath)); saveBitmap.compress(Bitmap.CompressFormat.JPEG, 60, out); //60代表压缩40%
如何将Bitmap保存为本地图片文件
怎么保存bmp滴呢。 用了copyPixelsToBuffer() 方法 当得到滴图片好像没有文件头。 不知道怎么加上去。 有人解答不?
android中人脸识别扫描人然后怎样将图像保存到本地数据库
用AndroidSDK中的Face Detector实现人脸识别流程是这样的:1. 读取一张图片至Bitmap (从Resource中,或是从手机相册中选取)2. 使用FaceDetector API分析Bitmap,将探测到的人脸数据以FaceDetector.Face存储在一个Face list中;3.将人脸框显示在图片上。
asp.net中服务器上的bitmap对象怎样保存到本地文件
服务器上的文件不能保存到浏览器本地文件,只能保存到服务器上,然后浏览器通过下载该文件保存到浏览器本地文件夹。
更多文章:
C语言怎么用递归法求阶乘?利用递归法计算斐波那契数列,由主函数指定输出该数列某一项,调用该函数计算该项的值,再有主函数输出
2024年7月5日 10:40
ospf协议是什么(OSPF路由协议,OSPF路由协议是什么意思)
2023年9月29日 10:20
output是什么意思中文翻译是什么意思(output什么意思)
2024年7月22日 09:32
selenium离线安装教程(求selenium IDE的下载步骤)
2024年7月20日 22:03
checkedlistbox全选(C#中checkedlistbox的用法)
2024年7月10日 10:03
extension of stay(超简单商务英语,要的是规范, 请正规翻译谢谢 :))
2024年7月20日 07:07
matlab软件feval函数(matlab中的feval函数怎么用)
2024年7月23日 20:23
个人主页的网站(申请个人主页的网站,不知道哪个是最好或挺好的)
2024年8月27日 05:45
java连接sqlserver数据库教程(JAVA连接SQL数据库)
2024年7月22日 23:34