将图像从相机保存到数据库[重复]

Posted

技术标签:

【中文标题】将图像从相机保存到数据库[重复]【英文标题】:Save image from the camera to a database [duplicate] 【发布时间】:2018-04-14 22:51:21 【问题描述】:

在我的示例应用程序中,我想保存相机和图库中的图像并保存到 sqlite 数据库。这是我的代码。

public class MainActivity extends AppCompatActivity 

private static final String TAG = MainActivity.class.getSimpleName();
private static final int GAL_CODE = 24;
private static final int CAM_CODE = 31;
private static final String ALLOW_KEY = "ALLOWED";
private static final String CAMERA_PREF = "camera_pref";

private ImageView imageView;
private EditText nameET, addrET;
private ImageButton galleryBtn, cameraBtn;
private Button saveBtn;

private String address;
private String name;

private DBHelper dbHelper;
private boolean fromCamera = false;
private boolean fromGallery = false;
private Uri outputFileUri;


@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    dbHelper = new DBHelper(this);

    imageView = (ImageView) findViewById(R.id.image);
    nameET = (EditText) findViewById(R.id.nameET);
    addrET = (EditText) findViewById(R.id.addrET);
    galleryBtn = (ImageButton) findViewById(R.id.galleryBtn);
    cameraBtn = (ImageButton) findViewById(R.id.cameraBtn);
    saveBtn = (Button) findViewById(R.id.saveBtn);

    galleryBtn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            selectImage();
        
    );

    cameraBtn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            takePhoto();
        
    );


    saveBtn.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            saveUser();
        
    );



private void takePhoto() 

    File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
    root.mkdirs();

    String fileName = "img_" + System.currentTimeMillis() + ".jpg";
    File sdCardImageMainDir = new File(root, fileName);
    outputFileUri = Uri.fromFile(sdCardImageMainDir);

    List<Intent> cameraIntents = new ArrayList<>();
    Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    PackageManager pm = getPackageManager();
    List<ResolveInfo> listCam = pm.queryIntentActivities(captureIntent, 0);

    for (ResolveInfo info: listCam)
        String packageName = info.activityInfo.packageName;
        Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        cameraIntents.add(intent);
    
    startActivityForResult(captureIntent, CAM_CODE);


private void saveUser() 

    name = nameET.getText().toString();
    address = addrET.getText().toString();

    if (!address.isEmpty() && !name.isEmpty())
        User user = new User(name, address);
        dbHelper.saveInputField(user);
        dbHelper.close();
        startActivity(new Intent(MainActivity.this, ShowActivity.class));
    



private void selectImage() 
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GAL_CODE);


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GAL_CODE && resultCode == RESULT_OK)
        Uri imgUri = data.getData();

        if (imgUri != null)
            if(saveImageToDB(imgUri))
                Toast.makeText(this, "Saved Image", Toast.LENGTH_SHORT).show();
            

        

    

    if (requestCode == CAM_CODE && resultCode == RESULT_OK)
        Bitmap bitmap = (Bitmap) data.getExtras().get("data");
        if (bitmap != null)
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            byte[] imageinByte = outputStream.toByteArray();

            User user = new User(name, address, imageinByte);
            dbHelper.saveInputField(user);  // error on this line
        
    


这是我的用户模型类。

public class User 

public int id;
public String name;
public String address;
public byte[] image;

public User() 


public User(int id) 
    this.id = id;


public User(String name, String address, byte[] camImage) 
    this.name = name;
    this.address = address;
    this.image = camImage;


public User(int id, String name, String address, byte[] camImage) 
    this.id = id;
    this.name = name;
    this.address = address;
    this.image = camImage;


public int getId() 
    return id;


public void setId(int id) 
    this.id = id;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


public String getAddress() 
    return address;


public void setAddress(String address) 
    this.address = address;


public byte[] getImage() 
    return image;


public void setImage(byte[] image) 
    this.image = image;


这里可以看到我的数据库助手类:

public class DBHelper 

private static final String DATABASE_NAME = "UsersDemo.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "profileInfo";

private static final String COL_ID = "databaseId";
private static final String COL_NAME = "name";
private static final String COL_ADDRESS = "addr";
private static final String COL_IMAGE = "image";

private Context mCtx;

private DatabaseManager databaseManager;
private SQLiteDatabase db;

public DBHelper (Context context)
    this.mCtx = context;
    databaseManager = new DatabaseManager(mCtx);


public DBHelper open() throws SQLException
    db = databaseManager.getWritableDatabase();
    return this;


public void close()
    databaseManager.close();


public void saveInputField(User user)
    ContentValues values = new ContentValues();

    values.put(COL_NAME, user.getName());
    values.put(COL_ADDRESS, user.getAddress());
    values.put(COL_IMAGE, user.getImage());

    db.insert(TABLE_NAME, null, values);
    db.close();


public User getCurrentUser(int id)
    Cursor cursor = db.query(true, TABLE_NAME, new String[]COL_ID, COL_NAME, COL_ADDRESS, COL_ID + "=?", new String[]String.valueOf(id), null, null, null, null);

    if (cursor != null && cursor.moveToFirst())

        User user = new User(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getBlob(1));
        return user;
    

    return null;



public void saveCamerayImage(byte[] imageBytes)
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_IMAGE, imageBytes);
    db.insert(TABLE_NAME, null, contentValues);


public void saveGalleryImage(byte[] imageBytes)
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_IMAGE, imageBytes);
    db.insert(TABLE_NAME, null, contentValues);


public byte[] getImage()
    Cursor cursor = db.query(true, TABLE_NAME, new String[]COL_IMAGE,, null, null, null, null, COL_ID + " DESC", "1");
    if (cursor.moveToFirst())
        byte[] blob = cursor.getBlob(cursor.getColumnIndex(COL_IMAGE));
        cursor.close();
        return blob;
    
    cursor.close();
    Toast.makeText(mCtx, "No Image Found", Toast.LENGTH_SHORT).show();
    return null;



public class DatabaseManager extends SQLiteOpenHelper 

    public DatabaseManager(Context context) 
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) 
        String db_create = "Create Table " + TABLE_NAME + " ("
                + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + COL_NAME + " TEXT, "
                + COL_ADDRESS + " TEXT, "
                + COL_IMAGE + " BLOB NOT NULL );";
        sqLiteDatabase.execSQL(db_create);
    

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) 
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
        onCreate(sqLiteDatabase);
    


在运行应用程序时,我在 logcat 中收到此错误消息。我似乎无法理解为什么它会显示这个。

我的日志如下:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long android.database.sqlite.SQLiteDatabase.insert(java.lang.String, java.lang.String, android.content.ContentValues)' on a null object reference
                                                                         at com.joey.example.dbsqlite.DBHelper.saveInputField(DBHelper.java:53)
                                                                         at com.joey.example.dbsqlite.MainActivity.onActivityResult(MainActivity.java:170)
                                                                         at android.app.Activity.dispatchActivityResult(Activity.java:6919)
                                                                         at android.app.ActivityThread.deliverResults(ActivityThread.java:4184)
                                                                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:4231) 
                                                                         at android.app.ActivityThread.-wrap20(ActivityThread.java) 
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                                         at android.os.Handler.dispatchMessage(Handler.java:110) 
                                                                         at android.os.Looper.loop(Looper.java:203) 
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6269) 
                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063) 
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924) 

有人可以解释如何解决此错误吗?谢谢。

【问题讨论】:

【参考方案1】:

你需要打电话

db = databaseManager.getWritableDatabase();

在您的saveInputField 中,先对db 对象进行任何操作。在处理db的其他方法中也这样做

【讨论】:

谢谢。这解决了它。再次感谢【参考方案2】:

将图像保存到 sqlite 是个坏主意,但是如果您还想更进一步,这里有代码

public static void insertPicture(byte[] data)


SQLiteDatabase db = thisAct.openOrCreateDatabase(ConstantCodes.IMAGE_DATABASE, 2, null);
ContentValues values = new ContentValues(1);
values.put("photo", data);
db.insert("photos", null, values);
db.close();

 

编码愉快!!

【讨论】:

谢谢,我已经修好了。【参考方案3】:

写入数据库时​​忘记调用方法中的 open() databaseManager.getWritableDatabase() 允许您写入数据库。

我也觉得调用方法时不需要返回DBHelper。改这个

 public DBHelper open() throws SQLException 
        db = databaseManager.getWritableDatabase();
        return this;
    

【讨论】:

以上是关于将图像从相机保存到数据库[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将相机图像上传到 Firebase

如何避免将从相机胶卷中挑选的图像保存到相机胶卷? [iOS]

使用手势将图像从 UIWebView 保存到相机胶卷

如何在 Android 上使用 MediaStore 将数据从相机保存到磁盘?

按名称将图像从相机保存到 sqlite

如何将图像从相机保存到 iPhone 画廊中的特定文件夹?