file_column简单的照片上传

介绍了一个名为file_column的Ruby on Rails库,它极大简化了处理文件上传的过程,并提供了如缩略图生成等实用功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.file_column 
git clone git://github.com/activescaffold/file_column.git 
gem install rmagick
model: 
file_column :photo, :magick => { 
    :versions => { "thumb" => "100x100>", "medium" => "640x480>" }
  }
view:
<%= image_tag(url_for_file_column('profile', 'photo', 'thumb')) if @profile && @profile.photo %><%= file_column_field 'profile', 'photo' %>


web example:
Attention: I will be speaking at the Canada on Rails conference, which will be held on April 13th-14th in Vancouver, Canada. David Heinemeier-Hansson will be giving a keynote and there are a lot of other big names on the list of speakers. I'm honored to give a talk about file_column and developing plugins in general.

This library makes handling of uploaded files in Ruby on Rails as easy as it should be. It helps you to not repeat yourself and write the same file handling code all over the place while providing you with nice features like keeping uploads during form redisplays, nice looking URLs for your uploaded files and easy integration with RMagick to resize uploaded images and create thumb-nails. Files are stored in the filesystem and the filename in the database.
Example

As you can judge a library best by looking at how to use it, here is a short example:

Just make the "image" column ready for handling uploaded files...


    class Entry < ActiveRecord::Base
        file_column :image
    end
    

... generate file fields that keep uploaded images during form redisplays to your view...


    <%= file_column_field "entry", "image" %>
    

... and display uploaded images in your view:


    <%= image_tag url_for_file_column("entry", "image") %>
    

It's just as easy! Why should it be any more difficult for a Rails application?

So what about the RMagick integration? Have a look:

To resize every uploaded image to a maximum size of 640x480, you just have to declare an additional option.


    class Entry < ActiveRecord::Base
        file_column :image, :magick => { :geometry => "640x480>" }
    end
    

You can even automatically create versions in different sizes that have nice filenames...


    class Entry < ActiveRecord::Base
        file_column :image, :magick => { 
          :versions => { "thumb" => "50x50", "medium" => "640x480>" }
        }
    end
    

... and display them in your view:

     <%= image_tag url_for_file_column("entry", "image") %>
     
值得注意的是,如果你用在其他的页面显示这张图片,必须存在这个实例变量@xxx
eg.
<% @profiles.each do |@profile|%>
<%= image_tag(url_for_file_column('profile', 'photo', 'thumb')) if @profile.photo %>
end

bug:
uninitialized constant FileColumn::ClassMethods::Inflector

solution:
go to file_column.rb
go to line 619
add “ActiveSupport::” before “Inflector.underscore(self.name).to_s,” to give =>
“ActiveSupport::Inflector.underscore(self.name).to_s,”

package com.chinaiatb.mrdoctor.utils; import android.Manifest; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.provider.MediaStore; import androidx.annotation.NonNull; import androidx.core.content.FileProvider; import android.provider.OpenableColumns; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.webkit.MimeTypeMap; import android.widget.TextView; import android.widget.Toast; import com.blankj.utilcode.util.LogUtils; import com.chinaiatb.mrdoctor.R; import com.chinaiatb.mrdoctor.base.ui.widget.ActionSheetDialog; import com.chinaiatb.mrdoctor.base.utils.FileUtils; import com.chinaiatb.mrdoctor.base.utils.PermissionUtils; import com.chinaiatb.mrdoctor.base.utils.ToastUtil; import com.chinaiatb.mrdoctor.configs.GlobalConstant; import com.chinaiatb.mrdoctor.configs.ParamsConfigs; import com.chinaiatb.mrdoctor.ui.test.friend.view.SelectImageActivity; import com.chinaiatb.mrdoctor.ui.test.model.Image; import com.google.android.material.snackbar.Snackbar; import com.huawei.hms.utils.IOUtils; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import static com.blankj.utilcode.util.StringUtils.getString; import static com.chinaiatb.mrdoctor.configs.IntentParameter.TAG; /** * description: * 2020/12/10. * auth:lihe */ public class AddPictureFileUtils { private ActionSheetDialog sheetDialog; private Activity mActivity; public AddPictureFileUtils(Activity activity, int singleOrMulti, boolean needCrop){ this.mActivity = activity; this.singleOrMulti = singleOrMulti; if(needCrop){ FILE_SAVEPATH = getSDPath(mActivity.getBaseContext()); // SELECT_FILE_SAVEPATH = getSDPath(mActivity.getBaseContext()); TEMP_DIR_PATH = ParamsConfigs.TEMP_SAVE_PATH_11; } } public AddPictureFileUtils(Activity activity, int singleOrMulti){ this.mActivity = activity; this.singleOrMulti = singleOrMulti; } private final static String AUTHORITY_NAME = "com.chinaiatb.mrdoctor.fileprovider"; private String FILE_SAVEPATH = ParamsConfigs.PICTURE_SAVE_PATH; private String TEMP_DIR_PATH = ParamsConfigs.TEMP_SAVE_PATH; private String SELECT_FILE_SAVEPATH = ParamsConfigs.SELECT_FILE_SAVE_PATH; private String FileFlag; private Uri origUri;//原始uri private Uri cropUri;//剪裁后的uri private Uri selectFileUri; private File uploadPicFile;//上传照片 private String uploadPicPath;//上传照片路径 private File uploadSelectFile;//上传文件 private String uploadSelectFilePath;//上传文件路径 private List<String> selectedFileNames = new ArrayList<>(); private File uploadOriPicFile;//原始照片 private String uploadOriPicPath;//原始照片路径 private String fileType; private boolean needCutPicture;//标记是否需要剪裁 private int singleOrMulti = SINGLE_CHOOSE;//标记单选还是多选 public static final int SINGLE_CHOOSE = 1;//照片单选f public static final int MULTI_CHOOSE = 2;//照片多选 /** 请求相册 */ public static final int REQUEST_CODE_GETIMAGE_BYSDCARD = 0; /** 请求相机 */ public static final int REQUEST_CODE_GETIMAGE_BYCAMERA = 1; /** 请求裁剪 */ public static final int REQUEST_CODE_GETIMAGE_BYCROP = 2; /** 请求文件 */ public static final int REQUEST_CODE_GETFILE = 3; private final int CROP = 200; /** 请求存储权限 */ private static final int REQUEST_CODE_STORAGE_PERMISSION = 4; /** * 检查相机存储权限 */ public void checkPremission(boolean needCutPicture,String fileFlag) { FileFlag = fileFlag; this.needCutPicture = needCutPicture; CharSequence[] items = { getString(R.string.str_img_from_camera), getString(R.string.str_img_from_album) }; imageChooseItem(items); } /* * 获取SDK=30及以上的存储路径 * */ public static String getSDPath(Context context) { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED);// 判断sd卡是否存在 if (sdCardExist) { if (Build.VERSION.SDK_INT>=29){ //Android10之后 sdDir = context.getExternalFilesDir(null); }else { sdDir = Environment.getExternalStorageDirectory();// 获取SD卡根目录 } } else { sdDir = Environment.getRootDirectory();// 获取跟目录 } return sdDir.toString(); } public void checkCameraPermissions(){ String[] permissions = new String[]{ // Manifest.permission.WRITE_EXTERNAL_STORAGE, // Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; //这里的this不是上下文,是Activity对象! PermissionUtils.getInstance().chekPermissions(mActivity, permissions, permissionsCameraResult,1); // ToastUtil.showLongToastTop("用于扫码登录、扫码签名、患者问题答复时添加图片或视频信息"); } //创建监听权限的接口对象 PermissionUtils.IPermissionsResult permissionsCameraResult = new PermissionUtils.IPermissionsResult() { @Override public void passPermissons() { onSheetDialogClick(1); } @Override public void forbitPermissons() { ToastUtil.showShortToast("没有权限!"); } }; public void checkFilePermissions(){ String[] permissions = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, }; //这里的this不是上下文,是Activity对象! PermissionUtils.getInstance().chekPermissions(mActivity, permissions, permissionsFileResult,1); } PermissionUtils.IPermissionsResult permissionsFileResult = new PermissionUtils.IPermissionsResult() { @Override public void passPermissons() { onSheetDialogClick(2); } @Override public void forbitPermissons() { ToastUtil.showShortToast("没有权限!"); } }; public void checkAlbumPermissions(){ String[] permissions = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, }; //这里的this不是上下文,是Activity对象! PermissionUtils.getInstance().chekPermissions(mActivity, permissions, permissionsAlbumResult,1); } //创建监听权限的接口对象 PermissionUtils.IPermissionsResult permissionsAlbumResult = new PermissionUtils.IPermissionsResult() { @Override public void passPermissons() { onSheetDialogClick(0); } @Override public void forbitPermissons() { ToastUtil.showShortToast("没有权限!"); } }; public void initDialog(){ if(null != sheetDialog){ return; } sheetDialog = new ActionSheetDialog(mActivity).builder(); sheetDialog.addSheetItem(getString(R.string.str_img_from_camera), null, new ActionSheetDialog.OnSheetItemClickListener() { @Override public void onClick(int which) { if(GlobalConstant.isAtRoomActivity){//还在视频过程中,不能拍照 ToastUtil.showShortToast("视频通话中,无法使用此功能"); }else{ checkCameraPermissions(); } } }); sheetDialog.addSheetItem(getString(R.string.str_img_from_album), null, new ActionSheetDialog.OnSheetItemClickListener() { @Override public void onClick(int which) { checkAlbumPermissions(); } }); //if (FileFlag=="1"){ if ("1".equals(FileFlag)){ sheetDialog.addSheetItem(getString(R.string.str_file_select), null, new ActionSheetDialog.OnSheetItemClickListener() { @Override public void onClick(int which) { checkFilePermissions(); } });} } /** * 相机选择和拍照 * @param items */ private void imageChooseItem(CharSequence[] items) { mActivity.runOnUiThread(new Runnable() { @Override public void run() { initDialog(); if (mActivity == null || mActivity.isDestroyed() || mActivity.isFinishing()) { return; } sheetDialog.show(); } }); } private void onSheetDialogClick(int position){ //判断是否挂载了SD卡 String storageState = Environment.getExternalStorageState(); if(storageState.equals(Environment.MEDIA_MOUNTED)){ File savedir = new File(FILE_SAVEPATH); File tempdir = new File(TEMP_DIR_PATH); if (!savedir.exists()) { savedir.mkdirs(); } if (!tempdir.exists()) { tempdir.mkdirs(); } } else{ ToastUtil.showShortToast("SD卡未挂载,不能操作照片"); return; } //输出裁剪的临时文件 String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date()); //照片命名 String origFileName = "byt_" + timeStamp + ".jpg"; String cropFileName = "byt_crop_" + timeStamp + ".jpg"; uploadOriPicPath = FILE_SAVEPATH + origFileName; uploadOriPicFile = new File(uploadOriPicPath); //裁剪头像的绝对路径 uploadPicPath = FILE_SAVEPATH + cropFileName; uploadPicFile = new File(uploadPicPath); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { origUri = FileProvider.getUriForFile(mActivity, AUTHORITY_NAME, uploadOriPicFile); }else{ origUri = Uri.fromFile(uploadOriPicFile); } cropUri = Uri.fromFile(uploadPicFile); //相册选图 if(position == 0) { if(singleOrMulti == SINGLE_CHOOSE){ startImagePick(); }else{ startActivity(); } } //手机拍照 else if(position == 1){ startActionCamera(); } //文件管理 else if(position == 2) { startActionFile(); } } private ArrayList<Image> mSelectImages = new ArrayList<>(); public static final int SELECT_IMAGE_REQUEST = 0x0011; private void startActivity() { Intent intent = new Intent(mActivity, SelectImageActivity.class); intent.putParcelableArrayListExtra("selected_images", mSelectImages); mActivity.startActivityForResult(intent, SELECT_IMAGE_REQUEST); } /** * 选择图片并直接裁剪 */ private void startImagePick() { // // 检查权限是否已授予 // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // if (!Environment.isExternalStorageManager()) { // // 如果没有权限,打开设置页面让用户授予权限 // Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); // mActivity.startActivityForResult(intent, REQUEST_CODE_STORAGE_PERMISSION); // return; // } // } // // 否则,执行正常的图片选择操作 Intent intent = new Intent(Intent.ACTION_PICK,null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); mActivity.startActivityForResult(Intent.createChooser(intent, "选择图片"),REQUEST_CODE_GETIMAGE_BYSDCARD); } /** * 相机拍照 */ private void startActionCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, selectFileUri/*this.getCameraTempFile()*/); // 添加这一句表示对目标应用临时授权该Uri所代表的文件 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } mActivity.startActivityForResult(intent, REQUEST_CODE_GETIMAGE_BYCAMERA); } private void startActionFile() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); intent.addCategory(Intent.CATEGORY_OPENABLE); // 添加可打开的文件分类 mActivity.startActivityForResult(Intent.createChooser(intent, "选择文件"), REQUEST_CODE_GETFILE); } /** * 拍照后裁剪 * @param data 原始图片 */ private void startActionCrop(Uri data, boolean fromCamera) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(data, "image/*"); if (fromCamera && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } intent.putExtra("return-data", false); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1);// 裁剪框比例 intent.putExtra("aspectY", 1); intent.putExtra("outputX", CROP); intent.putExtra("outputY", CROP); intent.putExtra("scale", true); intent.putExtra("scaleUpIfNeeded", true);// 去黑边 intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri); mActivity.startActivityForResult(intent, REQUEST_CODE_GETIMAGE_BYCROP); } private void startActionCrop2(File targetPhoto) { Intent intent = new Intent("com.android.camera.action.CROP"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // intent.setAction(Intent.ACTION_OPEN_DOCUMENT); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.setDataAndType(getUriByFileForN(targetPhoto), "image/*"); }else{ intent.setDataAndType(Uri.fromFile(targetPhoto), "image/*"); } intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri); intent.putExtra("return-data", false); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1);// 裁剪框比例 intent.putExtra("aspectY", 1); intent.putExtra("outputX", CROP); intent.putExtra("outputY", CROP); intent.putExtra("scale", true); intent.putExtra("scaleUpIfNeeded", true);// 去黑边 mActivity.startActivityForResult(intent, REQUEST_CODE_GETIMAGE_BYCROP); } private void startActionCrop3(Uri sourceUri) { uploadPicFile = FileUtils.createImageFile(mActivity.getApplication(), true); Intent intent = new Intent("com.android.camera.action.CROP"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // Android N 及以上版本,确保裁剪图片时可以访问文件 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.setDataAndType(sourceUri, "image/*"); } // 设置裁剪输出文件的路径,针对不同版本需要做不同的处理 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 10 及以上版本,需要通过 FileProvider 获取 content:// URI intent.putExtra(MediaStore.EXTRA_OUTPUT, FileUtils.uri); // FileUtils.uri 是通过 FileProvider 提供的 URI } else { // 对于 Android 9 以下版本,使用 Uri.fromFile 来处理 file:// URI Uri imgCropUri = Uri.fromFile(uploadPicFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, imgCropUri); } //intent.putExtra("return-data", true); // 设置为 true 来返回裁剪数据 // 设置裁剪的相关参数 intent.putExtra("return-data", false); // 不返回裁剪数据,返回文件 URI intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); // 裁剪框的比例 intent.putExtra("aspectY", 1); intent.putExtra("outputX", CROP); // 裁剪后的宽度 intent.putExtra("outputY", CROP); // 裁剪后的高度 intent.putExtra("scale", true); // 允许缩放 intent.putExtra("scaleUpIfNeeded", true); // 去掉黑边 Log.d("yyyyy4", "needCutPicture="); mActivity.startActivityForResult(intent, REQUEST_CODE_GETIMAGE_BYCROP); } private Uri getImageContentUri(File imageFile){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { String filePath = imageFile.getAbsolutePath(); Cursor cursor = mActivity.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", new String[]{filePath}, null); try { if (cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); Uri baseUri = Uri.parse("content://media/external/images/media"); return Uri.withAppendedPath(baseUri, "" + id); } else { if (imageFile.exists()) { Uri tempUri = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { tempUri = FileProvider.getUriForFile(mActivity, AUTHORITY_NAME, imageFile); }else{ tempUri = Uri.fromFile(imageFile); } return tempUri; } } }catch(Exception e){ e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } } } else { return Uri.fromFile(imageFile); } return null; } /** * Android7.0根据文件获取uri */ private Uri getUriByFileForN( File imageFile) { String filePath = imageFile.getAbsolutePath(); Cursor cursor = mActivity.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", new String[]{filePath}, null); if (cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(cursor .getColumnIndex(MediaStore.MediaColumns._ID)); Uri baseUri = Uri.parse("content://media/external/images/media"); return Uri.withAppendedPath(baseUri, "" + id); } else { Uri tempUri = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { tempUri = FileProvider.getUriForFile(mActivity, AUTHORITY_NAME, imageFile); }else{ tempUri = Uri.fromFile(imageFile); } return tempUri; } } /*************************************************************************/ /** * 选择相册图片时保存临时图片并获取图片临时路径 * @param data * @return */ private String getPhotoPathByUri(Intent data) { Uri contentUri = data.getData(); //copy file and send new file path String fileName = getFileName(contentUri); if (!TextUtils.isEmpty(fileName)) { File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName); copy(contentUri, copyFile); return copyFile.getAbsolutePath(); } return null; } public String getFileName(Uri uri) { if (uri == null) return null; String fileName = null; String path = uri.getPath(); int cut = path.lastIndexOf('/'); if (cut != -1) { fileName = path.substring(cut + 1); } return fileName; } public void copy( Uri srcUri, File dstFile) { try { InputStream inputStream = mActivity.getContentResolver().openInputStream(srcUri); if (inputStream == null) return; OutputStream outputStream = new FileOutputStream(dstFile); IOUtils.copy(inputStream, outputStream); inputStream.close(); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } } private String saveSelectedFile(Uri srcUri) { String fileName = getFileName(srcUri); if (!TextUtils.isEmpty(fileName)) { File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName); copy(srcUri, copyFile); return copyFile.getAbsolutePath(); } return null; } /*************************************************************************/ public String getUploadPicPath(){ return uploadPicPath; } public void setUploadPicPath(String uploadPicPath){ this.uploadPicPath = uploadPicPath; } public String getUploadOriPicPath(){ return uploadOriPicPath; } public void setUploadOriPicPath(String uploadOriPicPath){ this.uploadOriPicPath = uploadOriPicPath; } public String getUploadSelectFilePath(){ return uploadSelectFilePath; } public void setUploadSelectFilePath(String uploadSelectFilePath){ this.uploadSelectFilePath = uploadSelectFilePath; } public void dealOnActivityResult(int requestCode, int resultCode, Intent data,String AddFileFlag){ createFile(); Log.d("yyyyy0", "deal"); switch(requestCode) { case AddPictureFileUtils.REQUEST_CODE_GETIMAGE_BYCAMERA://拍照后的返回 if(!uploadOriPicFile.exists()) { //htc等手机可能存储在别的地方 Bitmap cameraBitMapData; if (data != null && data.hasExtra("data")) {//Intent带出 cameraBitMapData = data.getParcelableExtra("data"); } else { //存在系统路径 //获取系统拍照图片文件夹 Uri uri_DCIM = null; if (data.getData() != null) { uri_DCIM = data.getData(); } else { uri_DCIM = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } String DCIMPath = ""; //本次照片绝对路径 Cursor cr = mActivity.getContentResolver().query(uri_DCIM, new String[]{MediaStore.Images.Media.DATA}, null, null, MediaStore.Images.Media.DATE_MODIFIED + " desc");//降序排找最新的 if (cr.moveToFirst()) { DCIMPath = cr.getString(cr.getColumnIndex(MediaStore.Images.Media.DATA)); } cr.close(); cameraBitMapData = BitmapFactory.decodeFile(DCIMPath); } try { uploadOriPicFile.createNewFile(); //创建文件 FileOutputStream fos = new FileOutputStream(uploadOriPicFile); cameraBitMapData.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (IOException e) { LogUtils.w("=拍照图片保存发生异常!" + e); } } if(needCutPicture){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { try { startActionCrop3(getImageContentUri(uploadOriPicFile)); } catch (Exception e) { e.printStackTrace(); } } else { startActionCrop(getImageContentUri(uploadOriPicFile), true);//拍照后裁剪 } }else{ uplodTakePhotoFile(); } break; case AddPictureFileUtils.REQUEST_CODE_GETIMAGE_BYSDCARD://相册选择后的返回 Uri pickUri = data.getData(); Log.d("yyyyy", "pickUri: "+pickUri+"pickUri.getPath()"+pickUri.getPath()+"needCutPicture="+needCutPicture); if(pickUri != null && pickUri.getPath() != null){ if(needCutPicture){ Log.d("yyyyy1", "needCutPicture="+needCutPicture); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { try { Log.d("yyyyy2", "needCutPicture="+needCutPicture); //Uri fileUri = Uri.fromFile(new File(filePath)); Uri fileUri = FileProvider.getUriForFile(mActivity, "com.chinaiatb.mrdoctor.fileprovider", new File(getPhotoPathByUri(data))); //startActionCrop3(pickUri); startActionCrop3(fileUri); //startActionCrop2(new File(getPhotoPathByUri(data)));// 选图后裁剪 }catch (Exception e){ Log.d("yyyyy3", "needCutPicture="+needCutPicture); e.printStackTrace(); } }else{ startActionCrop2(new File(getPhotoPathByUri(data)));// 选图后裁剪 } }else{ uploadPhotoAlbumFile(data); } }else{ ToastUtil.showShortToast(getString(R.string.str_selected_pic_err)); } break; case AddPictureFileUtils.REQUEST_CODE_GETFILE: Uri pickFileUri = data.getData(); if (pickFileUri != null && pickFileUri.getPath() != null) { uploadSelectFilePath = getFilePathFromUri(mActivity.getApplicationContext(), pickFileUri); Log.d(TAG, "dealOnActivityResult: "+uploadSelectFilePath); fileType = getFileMimeType(mActivity.getApplicationContext(), pickFileUri); uploadSelectFile = new File(uploadSelectFilePath); String fileName = uploadSelectFile.getName(); selectedFileNames.add(fileName); uploadSelectFile(); if (uploadSelectFile.exists()) { Log.d(TAG, "文件保存成功"); // 执行其他操作 } else { Log.d(TAG, "文件保存失败"); // 处理文件保存失败的情况 } }break; case AddPictureFileUtils.SELECT_IMAGE_REQUEST://选择多张照片 if (data != null) { ArrayList<Image> selectImages = data.getParcelableArrayListExtra(SelectImageActivity.EXTRA_RESULT); uploadPhotoFiles(selectImages); } break; case REQUEST_CODE_GETIMAGE_BYCROP: // 单张剪裁后上传 Log.d("yyyyy11", "deal"); if (!uploadPicFile.exists()) { ToastUtil.showShortToast(getString(R.string.str_crop_pic_err)); } else { uploadAfterCutPhoto(); } break; } } public String getFileMimeType(Context context, Uri fileUri) { ContentResolver contentResolver = context.getContentResolver(); String fileMimeType = contentResolver.getType(fileUri); if (fileMimeType == null) { // 如果获取的MIME类型为空,尝试使用文件扩展名来推断MIME类型 String fileExtension = getFileExtension(context, fileUri); fileMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension); } return fileMimeType; } private String getFileExtension(Context context, Uri fileUri) { ContentResolver contentResolver = context.getContentResolver(); MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); // 从文件Uri获取文件名 String fileName = null; Cursor cursor = contentResolver.query(fileUri, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (displayNameIndex != -1) { fileName = cursor.getString(displayNameIndex); } } // 从文件名中获取扩展名 String fileExtension = null; if (fileName != null) { int dotIndex = fileName.lastIndexOf("."); if (dotIndex != -1 && dotIndex < fileName.length() - 1) { fileExtension = fileName.substring(dotIndex + 1).toLowerCase(); } } return fileExtension; } private String getFilePathFromUri(Context context, Uri uri) { String filePath = null; if (uri.getScheme().equals("content")) { ContentResolver contentResolver = context.getContentResolver(); Cursor cursor = contentResolver.query(uri, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATA); filePath = cursor.getString(columnIndex); cursor.close(); } } else if (uri.getScheme().equals("file")) { filePath = uri.getPath(); } return filePath; } /** * 文件为空时创建文件 */ public void createFile(){ if(null == uploadPicFile){ uploadPicFile = new File(uploadPicPath); } if(null == uploadOriPicFile){ uploadOriPicFile = new File(uploadOriPicPath); } } /** * 拍照后上传原始图片 */ public void uplodTakePhotoFile(){ if(null != addPictureFileListener){ addPictureFileListener.uploadFile(uploadOriPicFile, FileUtils.getFileFormat(uploadOriPicPath)); Log.d(TAG, "uplodTakePhotoFile: "+uploadOriPicPath); } } /** * 从相册直接选择的单张照片 * @param data */ public void uploadPhotoAlbumFile(Intent data){ if(null != addPictureFileListener){ addPictureFileListener.uploadFile(new File(getPhotoPathByUri(data)), FileUtils.getFileFormat(uploadPicPath)); Log.d(TAG, "uploadPhotoAlbumFile: "+FileUtils.getFileFormat(uploadPicPath)); } } public void uploadSelectFile(){ if (selectedFileNames != null) { // 打印selectedFileNames数组 for (String fileName : selectedFileNames) { Log.d("Array", fileName); } } else { Log.d("Array", "selectedFileNames is null"); } if(null != addPictureFileListener){ addPictureFileListener.uploadSelectFileList(selectedFileNames); addPictureFileListener.uploadSelectFile(uploadSelectFile, FileUtils.getFileFormat(uploadSelectFilePath)); } } /** * 一组照片上传 * @param selectImages */ public void uploadPhotoFiles(ArrayList<Image> selectImages){ if(null != addPictureFileListener){ addPictureFileListener.uploadFileList(selectImages); } } /** * 剪裁后的照片上传 */ public void uploadAfterCutPhoto(){ if(null != addPictureFileListener){ addPictureFileListener.uploadFile(uploadPicFile, FileUtils.getFileFormat(uploadPicPath)); } } private AddPictureFileListener addPictureFileListener; public interface AddPictureFileListener{ void uploadFile(File file, String suffix); void uploadSelectFile(File file, String suffix); void uploadFileList(ArrayList<Image> selectImages); void uploadSelectFileList(List<String> selectedFileNames); } public void setAddPictureFileListener(AddPictureFileListener addPictureFileListener){ this.addPictureFileListener = addPictureFileListener; } }哪些功能函数用到了getSDPath()函数
07-12
在Android Studio中,你可以通过以下步骤将本地照片上传到SQLite数据库: 1. **获取图片权限**: 首先,你需要在AndroidManifest.xml文件中添加读取存储权限: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 2. **选择图片**: 使用`ACTION_PICK`或`ACTION_GET_CONTENT`从用户相册选取图片,通常在Activity或Fragment中通过`Intent`实现: ```java Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, REQUEST_IMAGE PICKER); ``` 3. **处理结果**: 在`onActivityResult()`回调里,检查请求状态并处理选中的图片: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_PICKER && resultCode == RESULT_OK) { Uri selectedImage = data.getData(); // 从Uri加载Bitmap Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImage); } } ``` 4. **保存图片到文件路径**: 将图片转换为字节数组,然后存入临时文件或直接保存到SQLite BLOB字段,如果使用SQLiteOpenHelper,可能会创建一个专用的表用于存储大对象。 5. **插入数据库**: 创建或更新表,将BLOB字段和其他需要的数据一起插入: ```java ContentValues contentValues = new ContentValues(); contentValues.put("column_name", "file_path"); // 如果是文件路径而非BLOB contentValues.put("blob_column", blobFromBitmap(bitmap)); // 或者使用SQLite的rawQuery等方法 database.insertOrReplace("table_name", null, contentValues); ``` 6. **使用SQLite的BLOB字段**: 如果选择直接存储BLOB,可以像下面这样操作: ```java byte[] blobData = bitmapCompressToByteArray(Bitmap.CompressFormat.JPEG, 80); // 压缩质量可调整 contentValues.put("blob_column", blobData); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值