从图库android捕获和加载图像

时间:2013-12-05 06:39:38

标签: android image camera

在将图片从图库加载到我的imageview时,我确实感到困惑。我已经按照本教程http://developer.android.com/training/displaying-bitmaps/manage-memory.html以及此Strange out of memory issue while loading an image to a Bitmap object进行了操作。 当我使用三星选项卡它工作正常,但当我将它部署到galaxy note和其他设备时,我的应用程序崩溃并得到内存错误。 这是我的代码

package com.example.cobaandroid;



import java.io.InputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException; 
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

final int PICTURE_GALLERY = 0;
final int CAMERA_CAPTURE = 1;
final int PIC_CROP = 2;
public static final int MEDIA_IMAGE = 3;
private Uri picUri;
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tampilkanUserManual();
    Button ambilGambar = (Button)findViewById(R.id.ambil_gambar);
    Button gallery = (Button) findViewById(R.id.ambilGallery);
    ambilGambar.setOnClickListener(this);
    gallery.setOnClickListener(this);
    if(!supportCamera())
    {
        Toast.makeText(getApplicationContext(), "Maaf device anda tidak mendukung penggunaan kamera", Toast.LENGTH_LONG).show();
        finish();
    }
    Button exit = (Button)findViewById(R.id.exit);
    exit.setOnClickListener(this);
}

//Cek apakah device memiliki kamera
private Boolean supportCamera()
{
    if(getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
    {
        return true;
    }
    else return false;
}

// Button onClick 
public void onClick(View v)
{
    if(v.getId()==R.id.ambil_gambar)
    {
        try
        {
            //Intent untuk menggunakan kamera
            Intent intentAmbil = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intentAmbil,CAMERA_CAPTURE);
        }
        catch(ActivityNotFoundException activity)
        {
            String errorMessage = "ga support kamera";
            Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toast.show();
        }
    }
    else if(v.getId()==R.id.ambilGallery)
    {
        try
        {
            //intent untuk ngambil gambar di galeri
            Intent ambilGallery = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            ambilGallery.setType("image/*");
            startActivityForResult(ambilGallery, PICTURE_GALLERY);
        }
        catch(ActivityNotFoundException activity)
        {
            String errorMessage = "Tidak dapat mengambil gambar dari galeri";
            Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toast.show();
        }
    }
    else if(v.getId()==R.id.exit)
    {
        try
        {
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
        catch(ActivityNotFoundException ac)
        {
            Toast.makeText(getApplicationContext(), "Tidak dapat menutup aplikasi", Toast.LENGTH_LONG).show();
        }
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(resultCode==RESULT_OK)
    {
        if(requestCode==CAMERA_CAPTURE)
        {

            BitmapFactory.Options option = new BitmapFactory.Options();
            //option.inSampleSize = 8;
            option.inJustDecodeBounds = true;
            Bitmap hasilPoto = (Bitmap) data.getExtras().get("data");
            if(hasilPoto==null)
            {
                Toast.makeText(getApplicationContext(), "bitmap null", Toast.LENGTH_LONG).show();
            }
            picUri = data.getData();
            Toast.makeText(getApplicationContext(), picUri.getPath(), Toast.LENGTH_LONG).show();

            Intent cropIntent= new Intent (this, Crop.class);
            cropIntent.putExtra("data", picUri.toString());
            cropIntent.putExtra("gambar", hasilPoto);
            cropIntent.putExtra("kode","kamera");
            startActivity(cropIntent);
        }
        else if(requestCode==PICTURE_GALLERY)
        {
            // Resize gambar dari galeri
            Uri galeriUri = data.getData();
            String[] path = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(galeriUri,path,null,null,null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(path[0]);
            String gambarPath = cursor.getString(columnIndex);
            cursor.close();
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inJustDecodeBounds = true;
            opt.inSampleSize = calculateInSampleSize(opt, 50, 50);

            //Bitmap hasilPoto = BitmapFactory.decodeFile(gambarPath);
            Bitmap hasilPoto = BitmapFactory.decodeFile(gambarPath, opt);
            //hasilPoto = scaleDown(hasilPoto, 100, getApplicationContext());
            Intent cropIntents = new Intent(this,Crop.class);
            cropIntents.putExtra("data", galeriUri.toString());
            cropIntents.putExtra("kode","galeri");
            cropIntents.putExtra("gambar",hasilPoto);
            startActivity(cropIntents);
        }
    }
}

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 halfHeight = height/2;
        final int halfWidth = width/2;
        while((halfHeight/inSampleSize)>reqHeight && (halfWidth/inSampleSize)>reqWidth)
        {
            inSampleSize*=2;
        }
        long totalPixels = width*height/inSampleSize;
        final long totalReqPixelsCap = reqWidth*reqHeight*2;
        while(totalPixels > totalReqPixelsCap)
        {
            inSampleSize*=2;
            totalPixels/=2;
        }
    }
    return inSampleSize;
}
//fungsi untuk scaling gambar
private Bitmap scaleDown(Bitmap photo, int newHeight,Context contex)
{
    final float densityMultiplier = contex.getResources().getDisplayMetrics().density;
    int h = (int) (newHeight*densityMultiplier);
    int w = (int) (h*photo.getWidth()/(double)photo.getHeight());
    photo = Bitmap.createScaledBitmap(photo, w, h, true);
    return photo;
}

//tampilkan userManual
private void tampilkanUserManual()
{
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    LayoutInflater inflater = this.getLayoutInflater();
    View view = inflater.inflate(R.layout.activity_usermanual, null);
    builder.setView(view);
    builder.setPositiveButton("Ok", null);
    AlertDialog dialog = builder.create();
    dialog.show();
}

} 这是logcat

12-05 14:09:23.238: E/AndroidRuntime(6697): FATAL EXCEPTION: main
12-05 14:09:23.238: E/AndroidRuntime(6697): java.lang.OutOfMemoryError
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:389)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:418)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at com.example.cobaandroid.MainActivity.onActivityResult(MainActivity.java:150)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.app.Activity.dispatchActivityResult(Activity.java:4654)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2987)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3034)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.app.ActivityThread.access$1100(ActivityThread.java:127)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at  android.app.ActivityThread$H.handleMessage(ActivityThread.java:1188)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.os.Looper.loop(Looper.java:137)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at android.app.ActivityThread.main(ActivityThread.java:4511)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at java.lang.reflect.Method.invokeNative(Native Method)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at java.lang.reflect.Method.invoke(Method.java:511)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
12-05 14:09:23.238: E/AndroidRuntime(6697):     at dalvik.system.NativeStart.main(Native Method)

我还有另一个问题,当我使用意图打开相机并捕获任何问题时,我的应用程序总是崩溃,当我按下确定或保存按钮来保存图像。你能帮助我吗? 我真的很绝望:( 谢谢大家...

3 个答案:

答案 0 :(得分:0)

您需要使用BitmapFactory.Options来缩小显示图像的大小,尝试使用此方法返回可以在imageview中显示的位图。

private Bitmap shrinkmethod(String file, int width, int height) {
    BitmapFactory.Options bitopt = new BitmapFactory.Options();
    bitopt.inJustDecodeBounds = true;
    Bitmap bit = BitmapFactory.decodeFile(file, bitopt);

    int h = (int) Math.ceil(bitopt.outHeight / (float) height);
    int w = (int) Math.ceil(bitopt.outWidth / (float) width);

    if (h > 1 || w > 1) {
        if (h > w) {
            bitopt.inSampleSize = h;

        } else {
            bitopt.inSampleSize = w;
        }
    }
    bitopt.inJustDecodeBounds = false;
    bit = BitmapFactory.decodeFile(file, bitopt);

    return bit;

}

我从某处获得了这种方法,但我不记得了。 无论如何,我不赞成它。

希望有所帮助

答案 1 :(得分:0)

在您要上传的班级中使用以下代码         public void onClick(查看v){

Intent intent = new Intent(Userprofile.this,    FilePickerActivity.class);
      startActivityForResult(intent, REQUEST_PICK_FILE);
    }
});      

和文件选择器活动是          import java.io.File;          import java.io.FilenameFilter;          import java.util.ArrayList;          import java.util.Collections;          import java.util.Comparator;          import java.util.List;

     import android.app.ListActivity;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
     import android.widget.ArrayAdapter;
    import android.widget.ImageView;
   import android.widget.ListView;
   import android.widget.TextView;



    public class FilePickerActivity extends ListActivity {

public final static String EXTRA_FILE_PATH = "file_path";
public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions";
private final static String DEFAULT_INITIAL_DIRECTORY = "/";

protected File mDirectory;
protected ArrayList<File> mFiles;
protected FilePickerListAdapter mAdapter;
protected boolean mShowHiddenFiles = false;
protected String[] acceptedFileExtensions;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set the view to be shown if the list is empty
    LayoutInflater inflator = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View emptyView = inflator.inflate(R.layout.file_picker_empty_view, null);
    ((ViewGroup)getListView().getParent()).addView(emptyView);
    getListView().setEmptyView(emptyView);

    // Set initial directory
    mDirectory = new File(DEFAULT_INITIAL_DIRECTORY);

    // Initialize the ArrayList
    mFiles = new ArrayList<File>();

    // Set the ListAdapter
    mAdapter = new FilePickerListAdapter(this, mFiles);
    setListAdapter(mAdapter);

    // Initialize the extensions array to allow any file extensions
    acceptedFileExtensions = new String[] {};

    // Get intent extras
    if(getIntent().hasExtra(EXTRA_FILE_PATH)) {
        mDirectory = new File(getIntent().getStringExtra(EXTRA_FILE_PATH));
    }
    if(getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES)) {
        mShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
    }
    if(getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) {
        ArrayList<String> collection = getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS);
        acceptedFileExtensions = (String[]) collection.toArray(new String[collection.size()]);
    }
}

@Override
protected void onResume() {
    refreshFilesList();
    super.onResume();
}

/**
 * Updates the list view to the current directory
 */
protected void refreshFilesList() {
    // Clear the files ArrayList
    mFiles.clear();

    // Set the extension file filter
    ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions);

    // Get the files in the directory
    File[] files = mDirectory.listFiles(filter);
    if(files != null && files.length > 0) {
        for(File f : files) {
            if(f.isHidden() && !mShowHiddenFiles) {
                // Don't add the file
                continue;
            }

            // Add the file the ArrayAdapter
            mFiles.add(f);
        }

        Collections.sort(mFiles, new FileComparator());
    }
    mAdapter.notifyDataSetChanged();
}

@Override
public void onBackPressed() {
    if(mDirectory.getParentFile() != null) {
        // Go to parent directory
        mDirectory = mDirectory.getParentFile();
        refreshFilesList();
        return;
    }

    super.onBackPressed();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    File newFile = (File)l.getItemAtPosition(position);

    if(newFile.isFile()) {
        // Set result
        Intent extra = new Intent();
        extra.putExtra(EXTRA_FILE_PATH, newFile.getAbsolutePath());
        setResult(RESULT_OK, extra);
        // Finish the activity
        finish();
    } else {
        mDirectory = newFile;
        // Update the files list
        refreshFilesList();
    }

    super.onListItemClick(l, v, position, id);
}

private class FilePickerListAdapter extends ArrayAdapter<File> {

    private List<File> mObjects;

    public FilePickerListAdapter(Context context, List<File> objects) {
        super(context, R.layout.file_picker_list_item, android.R.id.text1, objects);
        mObjects = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = null;

        if(convertView == null) { 
            LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.file_picker_list_item, parent, false);
        } else {
            row = convertView;
        }

        File object = mObjects.get(position);

        ImageView imageView = (ImageView)row.findViewById(R.id.file_picker_image);
        TextView textView = (TextView)row.findViewById(R.id.file_picker_text);
        // Set single line
        textView.setSingleLine(true);

        textView.setText(object.getName());
        if(object.isFile()) {
            // Show the file icon
            imageView.setImageResource(R.drawable.file);
        } else {
            // Show the folder icon
            imageView.setImageResource(R.drawable.folder);
        }

        return row;
    }

}

private class FileComparator implements Comparator<File> {
    public int compare(File f1, File f2) {
        if(f1 == f2) {
            return 0;
        }
        if(f1.isDirectory() && f2.isFile()) {
            // Show directories above files
            return -1;
        }
        if(f1.isFile() && f2.isDirectory()) {
            // Show files below directories
            return 1;
        }
        // Sort the directories alphabetically
        return f1.getName().compareToIgnoreCase(f2.getName());
    }
}

private class ExtensionFilenameFilter implements FilenameFilter {
    private String[] mExtensions;

    public ExtensionFilenameFilter(String[] extensions) {
        super();
        mExtensions = extensions;
    }

    public boolean accept(File dir, String filename) {
        if(new File(dir, filename).isDirectory()) {
            // Accept all directory names
            return true;
        }
        if(mExtensions != null && mExtensions.length > 0) {
            for(int i = 0; i < mExtensions.length; i++) {
                if(filename.endsWith(mExtensions[i])) {
                    // The filename ends with the extension
                    return true;
                }
            }
            // The filename did not match any of the extensions
            return false;
        }
        // No extensions has been set. Accept all file extensions.
        return true;
    }
}

}

将以下代码粘贴到您调用文件piker活动

的主类中
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(resultCode == RESULT_OK) {
    switch(requestCode) {
    case REQUEST_PICK_FILE:
        if(data.hasExtra(FilePickerActivity.EXTRA_FILE_PATH)) {
     selectedFile = new           File(data.getStringExtra(FilePickerActivity.EXTRA_FILE_PATH));
            System.out.println("selectedFile");
            String s2=selectedFile.toString();



      //   mFilePathTextView.append("\r\n" + s+"\r\n");       
        //   newValues.put("fio", "?????? ???? ?????????");

        /////////// insert picture to blob field ///////////////////// 
           try {
               FileInputStream instream = new FileInputStream(s2); 
               BufferedInputStream bif = new BufferedInputStream(instream); 
               byteImage1 = new byte[bif.available()]; 
               bif.read(byteImage1);
        } catch (Exception e) {
            // TODO: handle exception
        }
           try {
               img.setImageBitmap(BitmapFactory.decodeByteArray(byteImage1, 0, byteImage1.length));
        } catch (Exception e) {
            // TODO: handle exception
        }


   //img.setImageBitmap(byteImage1);




        }
    }                             

答案 2 :(得分:0)

我能看到的是你似乎没有调用缩小第一个if-else块中图像的方法 - 即* if(requestCode == CAMERA_CAPTURE)*相反,我看到你做了以下:

// option.inSampleSize = 8;

你不应该在这里调用calculateInSampleSize方法吗?

然后,当你完成缩小位图时,你应该将injustdecodebounds设置为false,即

 option.inJustDecodeBounds = false;

您还可以尝试通过将配置设置为

的RGB565来缩小图像的大小
 opt.inPreferredConfig = Config.RGB_565;