在两个活动之间传递位图

我正在开发一个绘画应用程序,我想从一个活动传递到另一个位图图像,但项目没有响应。 我将相对布局的屏幕截图转换为位图,并通过意向传递,但问题没有解决。 这是我的代码….

DrawingActivity

package com.newdrawing; public class DrawingActivity extends Activity { private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; private Paint mPaint; MyDrawView myDrawView; RelativeLayout parent; Bitmap bitmap; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawing); parent = (RelativeLayout) findViewById(R.id.singleparent); myDrawView = new MyDrawView(this); parent.addView(myDrawView); Activity context; //RelativeLayout item = (RelativeLayout)findViewById(R.id.item); View child = getLayoutInflater().inflate(R.layout.trans, null); parent.addView(child); } public void color(View v) { switch (v.getId()) { case R.id.button3: parent.setBackgroundColor(Color.RED); break; case R.id.button4: parent.setBackgroundColor(Color.GREEN); break; case R.id.button5: parent.setBackgroundColor(Color.BLUE); break; } } public void save(View v) { parent.setDrawingCacheEnabled(true); bitmap=parent.getDrawingCache(); parent.setDrawingCacheEnabled(false); Log.e("Bitmap",String.valueOf(bitmap)); // send(); //Canvas c = new Canvas(bitmap); //.draw(c); // File outputFile; // Where to save it //FileOutputStream out = new FileOutputStream(imageFile); // boolean success = bitmap.compress(CompressFormat.PNG, 100, out); // out.close(); Intent i = new Intent(this, ImageActivity.class); ByteArrayOutputStream bs = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 50, bs); byte[] byteArray = bs.toByteArray(); i.putExtra("byteArray", byteArray); startActivity(i); } private void send() { Intent i9=new Intent(DrawingActivity.this,ImageActivity.class); i9.putExtra("Image",bitmap); startActivity(i9); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_drawing, menu); return true; } public class MyDrawView extends View { public MyDrawView(Context c) { super(c); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(0xFF000000); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(3); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawColor(Color.TRANSPARENT); canvas.drawPath(mPath, mPaint); } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } public void clear(){ mBitmap.eraseColor(Color.TRANSPARENT); invalidate(); System.gc(); } } } 

ImageActivity

 package com.newdrawing; public class ImageActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image); Intent i = getIntent(); ImageView img=(ImageView)findViewById(R.id.image11); /* if(getIntent().hasExtra("byteArray")) { Bitmap b = BitmapFactory.decodeByteArray( getIntent().getByteArrayExtra("byteArray"),0,getIntent().getByteArrayExtra("byteArray").length); img.setImageBitmap(b); Log.e("Bitmap",String.valueOf(b)); }*/ Bundle extras = getIntent().getExtras(); byte[] byteArray = extras.getByteArray("byteArray"); Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); img.setImageBitmap(bmp); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_image, menu); return true; } } 

地点报告

 10-16 10:39:22.653: E/AndroidRuntime(339): FATAL EXCEPTION: main 10-16 10:39:22.653: E/AndroidRuntime(339): java.lang.IllegalStateException: Could not execute method of the activity 10-16 10:39:22.653: E/AndroidRuntime(339): at android.view.View$1.onClick(View.java:2072) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.view.View.performClick(View.java:2408) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.view.View$PerformClick.run(View.java:8816) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.os.Handler.handleCallback(Handler.java:587) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.os.Handler.dispatchMessage(Handler.java:92) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.os.Looper.loop(Looper.java:123) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.app.ActivityThread.main(ActivityThread.java:4627) 10-16 10:39:22.653: E/AndroidRuntime(339): at java.lang.reflect.Method.invokeNative(Native Method) 10-16 10:39:22.653: E/AndroidRuntime(339): at java.lang.reflect.Method.invoke(Method.java:521) 10-16 10:39:22.653: E/AndroidRuntime(339): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 10-16 10:39:22.653: E/AndroidRuntime(339): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 10-16 10:39:22.653: E/AndroidRuntime(339): at dalvik.system.NativeStart.main(Native Method) 10-16 10:39:22.653: E/AndroidRuntime(339): Caused by: java.lang.reflect.InvocationTargetException 10-16 10:39:22.653: E/AndroidRuntime(339): at com.newdrawing.DrawingActivity.save(DrawingActivity.java:91) 10-16 10:39:22.653: E/AndroidRuntime(339): at java.lang.reflect.Method.invokeNative(Native Method) 10-16 10:39:22.653: E/AndroidRuntime(339): at java.lang.reflect.Method.invoke(Method.java:521) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.view.View$1.onClick(View.java:2067) 10-16 10:39:22.653: E/AndroidRuntime(339): ... 11 more 10-16 10:39:22.653: E/AndroidRuntime(339): Caused by: java.lang.IllegalStateException: Can't compress a recycled bitmap 10-16 10:39:22.653: E/AndroidRuntime(339): at android.graphics.Bitmap.checkRecycled(Bitmap.java:180) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.graphics.Bitmap.compress(Bitmap.java:572) 10-16 10:39:22.653: E/AndroidRuntime(339): ... 15 more 

Solutions Collecting From Web of "在两个活动之间传递位图"

你可以简单地尝试下面 –

 Intent i = new Intent(this, Second.class) i.putExtra("Image", bitmap); startActivity(i) 

而在Second.class

 Bitmap bitmap = (Bitmap) intent.getParcelableExtra("Image"); 

看看这里如果你想在发送到下一个活动之前压缩你的Bitmap只是看看下面 –

 Intent i = new Intent(this, NextActivity.class); Bitmap b; // your bitmap ByteArrayOutputStream bs = new ByteArrayOutputStream(); b.compress(Bitmap.CompressFormat.PNG, 50, bs); i.putExtra("byteArray", bs.toByteArray()); startActivity(i); 

在你的nextactivity –

 if(getIntent().hasExtra("byteArray")) { ImageView previewThumbnail = new ImageView(this); Bitmap b = BitmapFactory.decodeByteArray( getIntent().getByteArrayExtra("byteArray"),0,getIntent() .getByteArrayExtra("byteArray").length); previewThumbnail.setImageBitmap(b); } 

我在这个 SOpost中回答了类似的问题。 我的解决scheme会将图像保存在其他应用程序无法访问的设备的内部存储器中(在无根手机上)。 然后,我们可以简单地解码文件,并在imageview中显示它。 它可以防止TranscationTooLargeexception,因为您不能超过1mb传递包的限制。

我认为在大多数情况下,可以将位图放在一个静态引用上,当接收活动不再需要时,静态引用应该是空的。

这样,它非常快,不需要转换或编码和解码。 它也不留下痕迹。

如果你的图像是静态的,并在可绘制的文件夹等等所以发送位图从意图到下一个活动非常昂贵(对于机器:))所以现在是最好的方法是首先在strings.xml创build像这里的string-array

 <resources> <string name="app_name">Gallery App</string> <string-array name="images"> <item>@drawable/img1</item> <item>@drawable/img2</item> <item>@drawable/img3</item> <item>@drawable/img4</item> <item>@drawable/img5</item> <item>@drawable/img6</item> </string-array> </resources> 

然后在你的活动中获取与上面声明的图像相关的images列表。

1: – 声明TypeArray typeArray的实例

2:-Assign typeArray = getResources().obtainTypedArray(R.array.images);

3: – 声明您的列表,并逐一添加每个项目 – >

  ArrayList list = new ArrayList(); for (int i = 0 ;i< typedArray.length() ; i++){ Bitmap bitmap = BitmapFactory.decodeResource(getResources(),typedArray.getResourceId(i ,-1)); list.add(bitmap); } 

4: – 当然,现在你将在你的ArrayAdapter设置这个列表

 view.setAdapter(new ArrayAdapter(this , R.layout.viewImages , list)); 

5:发送cliked bitmapimage到你的下一个活动

  view.setOnItemClickedListener(new AdapterView.OnItemClickedListener(){ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent i = new Intent(MainActivity.this , DetailedImageActivity.class); int imageId = typedArray.getResourceId(position , -1); i.putExtra("imageId",imageId) ; Log.i("ResourceId ","here"); startActivity(i); } }); 

6: – 获取您的位图ID并获取您的位图图像

 public class DetailedImageActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detailed_image); ImageView imageView = (ImageView) findViewById(R.id.detailImageView); String title = getIntent().getStringExtra("title"); int imageId = getIntent().getExtras().getInt("imageId") ; Bitmap image = BitmapFactory.decodeResource(getResources() ,imageId); imageView.setImageBitmap(image); } } 

有很多方法:

1)

位图实现了Parcelable,所以你可以随时传递它的意图:

 Intent intent = new Intent(this, NewActivity.class); intent.putExtra("BitmapImage", bitmap); 

并在另一端检索它:

 Intent intent = getIntent(); Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage"); 

2)

在将其添加到意图之前将其转换为字节数组,然后将其发送出去并进行解码。

//转换为字节数组

 ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); Intent in1 = new Intent(this, Activity2.class); in1.putExtra("image",byteArray); 

然后在活动2中:

 byte[] byteArray = getIntent().getByteArrayExtra("image"); Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 

在你的logcat中说明

 10-16 10:39:22.653: E/AndroidRuntime(339): Caused by: java.lang.IllegalStateException: Can't compress a recycled bitmap 10-16 10:39:22.653: E/AndroidRuntime(339): at android.graphics.Bitmap.checkRecycled(Bitmap.java:180) 10-16 10:39:22.653: E/AndroidRuntime(339): at android.graphics.Bitmap.compress(Bitmap.java:572) 

在传递给ImageActivity之前,您的位图被回收。 您可以使位图静态,以便它不会被回收。

您可以使用bundle将位图从一个活动传递到另一个活动

将您的图像添加到字节数组:

 ArrayList<byte[]> image=new ArrayList<byte[]>(); Bundle b = new Bundle(); Intent it=new Intent(getBaseContext(),your.class); b.putByteArray("image", image.get(position)); it.putExtras(b); startActivity(it); 

让你的形象从捆绑创build接收器活动

我正在寻找它,并最终在https://eazyprogramming.blogspot.com/2013/01/passing-image-between-activities.html#comment-form

在第一个活动

 Intent intent=new Intent(FirstClass.this, SecondClass.class); Bundle bundle=new Bundle(); bundle.putInt("image",R.drawable.ic_launcher); intent.putExtras(bundle); startActivity(intent); 

在第二Acticity:

 Bundle bundle=this.getIntent().getExtras(); int pic=bundle.getInt("image"); v.setImageResource(pic); 

另一种方法:在第一次活动中:

 Bundle extras = getIntent().getExtras(); byte[] b = extras.getByteArray("picture"); Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length); ImageView image = (ImageView) findViewById(R.id.imageView1); image.setImageBitmap(bmp); 

在第二Acticity:

 Bundle extras = getIntent().getExtras();byte[] b = extras.getByteArray("picture");Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);ImageView image = (ImageView) findViewById(R.id.imageView1);