How to select a database blob and transform into bitmap?

2

I have the following error in my project, I select an image from the gallery I transform it into a byte in the database, but at the moment of loading it to imageView it does not appear and not from the error in the application, I'm not touching the part of the code to take photo but if someone has some better code because the image loses the quality, I appreciate the help.

public class Main extends AppCompatActivity {

    private int REQUEST_CAMERA = 0, SELECT_FILE = 1;
    private Button btnSelect;
    private Button btnCamera;
    private Button btnSave;
    private ImageView ivImage;
    private String Chave;
    banco db = new banco(this);
    SQLiteDatabase banco;
    String local;
    byte[] imagem;

    Bitmap bitmap;


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

        ivImage = (ImageView) findViewById(R.id.ivImage);
        btnSelect = (Button) findViewById(R.id.btnSelect);
        btnCamera = (Button) findViewById(R.id.btnCamera);
        btnSave = (Button) findViewById(R.id.btnSalvar);


        btnSelect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Chave = "Selecionar";
                galleryIntent();

            }
        });

        btnCamera.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Chave = "Camera";
                cameraIntent();

            }
        });

        btnSave.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                banco = db.getReadableDatabase();
                banco.execSQL("insert into tabela (imagem) values('"+imagem+"')");
                Toast.makeText(Main.this, imagem+" Imagem salva!", Toast.LENGTH_SHORT).show();
                banco.close();

            }
        });

        carregar();

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case Utility.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if(Chave.equals("Camera"))
                        cameraIntent();
                    else if(Chave.equals("Selecionar"))
                        galleryIntent();
                }
                break;
        }
    }

    private void galleryIntent()
    {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
    }

    private void cameraIntent()
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, REQUEST_CAMERA);
    }

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

        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == SELECT_FILE)
                onSelectFromGalleryResult(data);
            else if (requestCode == REQUEST_CAMERA)
                onCaptureImageResult(data);
        }

    }

    private void onCaptureImageResult(Intent data) {
        bitmap = (Bitmap) data.getExtras().get("data");
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

        File destination = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");

        local = destination.getName();

        FileOutputStream fo;
        try {
            destination.createNewFile();
            fo = new FileOutputStream(destination);
            fo.write(bytes.toByteArray());
            fo.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        ivImage.setImageBitmap(bitmap);

    }

    @SuppressWarnings("deprecation")
    private void onSelectFromGalleryResult(Intent data) {

        bitmap = null;
        if (data != null) {
            try {

                bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        ivImage.setImageBitmap(bitmap);

        Bitmap bitmap2 = ((BitmapDrawable)ivImage.getDrawable()).getBitmap();
        ByteArrayOutputStream saida = new ByteArrayOutputStream();
        bitmap2.compress(Bitmap.CompressFormat.PNG,100,saida);
        imagem = saida.toByteArray();

        Toast.makeText(Main.this, imagem.toString(), Toast.LENGTH_SHORT).show();
    }




    public void carregar() {

        banco = db.getReadableDatabase();

        Cursor cur = banco.rawQuery("select * from tabela", null);

        cur.moveToFirst();

        if(cur.isAfterLast()== false) {

            cur.moveToLast();

            byte[] image = cur.getBlob(cur.getColumnIndex("imagem"));

            if (image != null) {
                Bitmap bmp = BitmapFactory.decodeByteArray(image, 0, image.length);
                ivImage.setImageBitmap(bmp);
            }
        }

    }


}
    
asked by anonymous 15.10.2016 / 00:59

2 answers

1

Your image is certainly too large to be drawn in surface of a bitmap because it pops up the maximum size allowed for Android texture memory. If you use Android Monitor within Android Studio you will see a lot of warning of type "Bitmap too large to be uploaded into a texture" . You need to do downsampling the same. Avoid manipulating bitmaps directly, use a library for this. It's much more complicated to deal with bitmaps on the android than you might think. Very much!

Note: In cases of low system memory remaining, the file read operations for an array of bytes in memory may fail. In extreme low memory situations, not even using a library with Glide can prevent such errors from occurring, but Glide graciously deals with them, plus an advantage of using such a library.

So study the Google Glide library, which does all the work for you to read the image on a background thread (avoiding crashing the user interface) and still considers screen-orientation rotations (which would give you an NullReferenceException exception), and still implement an image cache to improve application performance.

Install Glide by adding the following line to your Gradle:

dependencies {
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile 'com.android.support:support-v4:19.1.0'
}

Once installed glide modify your display routine to:

public void carregar() {

    banco = db.getReadableDatabase();

    Cursor cur = banco.rawQuery("select * from tabela", null);

    cur.moveToFirst();

    if(cur.isAfterLast()== false) {

        cur.moveToLast();

        byte[] image = cur.getBlob(cur.getColumnIndex("imagem"));

        if (image != null) {

            Glide.with(this)
                .load(image)
                .asBitmap()
                .into(ivImage);

        }
    }

Note: I noticed an error in your implementation of image capture by the camera. You are only getting the thumbnail of the captured image. This is a common mistake / catch-up for those who start working with the camera on Android. I have an answer exactly to what you can see here: Working with the camera or gallery

    
26.10.2016 / 17:29
0

Here is a basic example of how to manipulate images in Sqlite:

ADD IMAGE:

public void add( byte[] image) throws SQLiteException{
    ContentValues cv = new  ContentValues();
    cv.put(KEY_IMAGE,   image);
    database.insert( DB_TABLE, null, cv );
}

To load the image use the getBlob method:

byte[] image = cursor.getBlob(1);
    
31.10.2016 / 21:11