한 활동에서 다른 활동으로 비트 맵 객체를 전달하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/2459524

문제

내 활동에서 나는 a를 만듭니다 Bitmap 객체와 다른 것을 시작해야합니다 Activity, 어떻게 통과 할 수 있습니까? Bitmap 하위 활동 (시작될 것)의 객체?

도움이 되었습니까?

해결책

Bitmap 구현 Parcelable, 따라서 항상 의도로 전달할 수 있습니다.

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

다른 쪽 끝에서 검색하십시오.

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

다른 팁

실제로 비트 맵을 소포로 전달하면 "Java 바인더 고장"오류가 발생합니다. 비트 맵을 바이트 배열로 전달하여 다음 활동에 표시를 위해 빌드하십시오.

여기에서 내 솔루션을 공유했습니다.
번들을 사용하여 Android 활동 사이에 이미지 (비트 맵)를 어떻게 전달합니까?

활동 사이의 번들에서 파싱 가능한 비트 맵을 통과하는 것은 페어싱 가능 (1MB)의 크기 제한 때문에 좋은 생각이 아닙니다. 내부 저장소에 파일에 비트 맵을 저장하고 여러 활동에서 저장된 비트 맵을 검색 할 수 있습니다. 다음은 샘플 코드입니다.

파일에 비트 맵을 저장합니다 Myimage 내부 스토리지에서 :

public String createImageFromBitmap(Bitmap bitmap) {
    String fileName = "myImage";//no .png or .jpg needed
    try {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
        fo.write(bytes.toByteArray());
        // remember close file output
        fo.close();
    } catch (Exception e) {
        e.printStackTrace();
        fileName = null;
    }
    return fileName;
}

그런 다음 다음 활동에서는 다음 코드를 사용 하여이 파일 MyImage를 비트 맵으로 해독 할 수 있습니다.

//here context can be anything like getActivity() for fragment, this or MainActivity.this
Bitmap bitmap = BitmapFactory.decodeStream(context.openFileInput("myImage"));

메모 NULL 및 스케일링 비트 맵을 많이 점검하는 것이 었습니다.

이미지가 너무 커서 저장소에 저장 및로드 할 수없는 경우 "ISCHANGINGCONFIGURATIONS"에만 ONDESTORY에서 NULL로 재설정되는 비트 맵 (수신 활동 내부)에 대한 전역 정적 참조를 사용하는 것이 좋습니다. 진실을 반환합니다.

의도의 크기 제한이 있기 때문입니다. 공개 정적 개체를 사용하여 서비스에서 방송으로 비트 맵을 통과합니다 ....

public class ImageBox {
    public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>(); 
}

내 서비스를 통과하십시오

private void downloadFile(final String url){
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                Bitmap b = BitmapFromURL.getBitmapFromURL(url);
                synchronized (this){
                    TaskCount--;
                }
                Intent i = new Intent(ACTION_ON_GET_IMAGE);
                ImageBox.mQ.offer(b);
                sendBroadcast(i);
                if(TaskCount<=0)stopSelf();
            }
        });
    }

내 브로드 카스트 레터

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            LOG.d(TAG, "BroadcastReceiver get broadcast");

            String action = intent.getAction();
            if (DownLoadImageService.ACTION_ON_GET_IMAGE.equals(action)) {
                Bitmap b = ImageBox.mQ.poll();
                if(b==null)return;
                if(mListener!=null)mListener.OnGetImage(b);
            }
        }
    };

압축하고 보내십시오 Bitmap

허용 된 답변은 다음과 같이 충돌합니다 Bitmap 너무 큽니다. 나는 그것이 A라고 믿는다 1MB 한계. 그만큼 Bitmap 다음과 같은 다른 파일 형식으로 압축해야합니다. JPG a ByteArray, 그런 다음 An을 통해 안전하게 통과 할 수 있습니다 Intent.

구현

함수는 별도의 스레드에 포함되어 있습니다 코 틀린 코 루틴 때문에 Bitmap 압축 후에 혼란이 발생합니다 Bitmap URL에서 생성됩니다 String. 그만큼 Bitmap 생성은 피하기 위해 별도의 스레드가 필요합니다 응답하지 않음 (ANR) 오류.

사용 된 개념

  • 코 틀린 코 루틴 메모.
  • 그만큼 로딩, 내용, 오류 (LCE) 패턴은 아래에서 사용됩니다. 관심이 있으시면 그것에 대해 더 배울 수 있습니다 이 대화와 비디오.
  • 살아있다 데이터를 반환하는 데 사용됩니다. 나는 내가 가장 좋아하는 것을 컴파일했다 살아있다 자원 이 노트.
  • ~ 안에 3 단계, toBitmap() a Kotlin 확장 기능 해당 라이브러리가 앱 종속성에 추가되어야합니다.

암호

1. 압축 Bitmap 에게 JPG ByteArray 그것이 만들어진 후.

저장소 .kt

suspend fun bitmapToByteArray(url: String) = withContext(Dispatchers.IO) {
    MutableLiveData<Lce<ContentResult.ContentBitmap>>().apply {
        postValue(Lce.Loading())
        postValue(Lce.Content(ContentResult.ContentBitmap(
            ByteArrayOutputStream().apply {
                try {                     
                    BitmapFactory.decodeStream(URL(url).openConnection().apply {
                        doInput = true
                        connect()
                    }.getInputStream())
                } catch (e: IOException) {
                   postValue(Lce.Error(ContentResult.ContentBitmap(ByteArray(0), "bitmapToByteArray error or null - ${e.localizedMessage}")))
                   null
                }?.compress(CompressFormat.JPEG, BITMAP_COMPRESSION_QUALITY, this)
           }.toByteArray(), "")))
        }
    }

ViewModel.kt

//Calls bitmapToByteArray from the Repository
private fun bitmapToByteArray(url: String) = liveData {
    emitSource(switchMap(repository.bitmapToByteArray(url)) { lce ->
        when (lce) {
            is Lce.Loading -> liveData {}
            is Lce.Content -> liveData {
                emit(Event(ContentResult.ContentBitmap(lce.packet.image, lce.packet.errorMessage)))
            }
            is Lce.Error -> liveData {
                Crashlytics.log(Log.WARN, LOG_TAG,
                        "bitmapToByteArray error or null - ${lce.packet.errorMessage}")
            }
        }
    })
}

2. 이미지를 다음과 같이 전달합니다 ByteArray an Intent.

이 샘플에서는 a에서 전달됩니다 파편 a 서비스. 둘 사이에 공유되는 경우 동일한 개념입니다. 활동.

Fragment.kt

ContextCompat.startForegroundService(
    context!!,
    Intent(context, AudioService::class.java).apply {
        action = CONTENT_SELECTED_ACTION
        putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
    })

3. 변환 ByteArray 돌아가다 Bitmap.

utils.kt

fun ByteArray.byteArrayToBitmap(context: Context) =
    run {
        BitmapFactory.decodeByteArray(this, BITMAP_OFFSET, size).run {
            if (this != null) this
            // In case the Bitmap loaded was empty or there is an error I have a default Bitmap to return.
            else AppCompatResources.getDrawable(context, ic_coinverse_48dp)?.toBitmap()
        }
    }

늦을 수도 있지만 도움이 될 수 있습니다. 첫 번째 조각이나 활동에서 클래스를 선언합니다 ... 예를 들어

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

        if (requestCode == PICK_IMAGE_REQUEST && data != null && data.getData() != null) {
            filePath = data.getData();
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), filePath);
                imageView.setImageBitmap(bitmap);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                constan.photoMap = bitmap;
            } catch (IOException e) {
                e.printStackTrace();
            }
       }
    }

public static class constan {
    public static Bitmap photoMap = null;
    public static String namePass = null;
}

그런 다음 두 번째 클래스/조각 에서이 작업을 수행합니다.

Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;

도움이되기를 바랍니다.

비트 맵 전송을 만들 수 있습니다. 이 시도....

첫 번째 수업에서 :

1) 생성 :

private static Bitmap bitmap_transfer;

2) 게터와 세터를 만듭니다

public static Bitmap getBitmap_transfer() {
    return bitmap_transfer;
}

public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
    bitmap_transfer = bitmap_transfer_param;
}

3) 이미지 설정 :

ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());

그런 다음 두 번째 클래스에서 :

ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));

위의 모든 솔루션은 나에게 작동하지 않으며 BitMap을 다음과 같이합니다. parceableByteArray 또한 오류가 발생합니다 android.os.TransactionTooLargeException: data parcel size.

해결책

  1. 내부 저장소에 비트 맵을 다음과 같이 저장했습니다.
public String saveBitmap(Bitmap bitmap) {
        String fileName = "ImageName";//no .png or .jpg needed
        try {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
            FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
            fo.write(bytes.toByteArray());
            // remember close file output
            fo.close();
        } catch (Exception e) {
            e.printStackTrace();
            fileName = null;
        }
        return fileName;
    }
  1. 그리고 보내십시오 putExtra(String) ~처럼
Intent intent = new Intent(ActivitySketcher.this,ActivityEditor.class);
intent.putExtra("KEY", saveBitmap(bmp));
startActivity(intent);
  1. 다른 활동에서 다음과 같이받습니다.
if(getIntent() != null){
  try {
           src = BitmapFactory.decodeStream(openFileInput("myImage"));
       } catch (FileNotFoundException e) {
            e.printStackTrace();
      }

 }


제 경우에는 위에서 언급 한 방식이 저에게 효과가 없었습니다. 비트 맵을 의도에 넣을 때마다 두 번째 활동이 시작되지 않았습니다. 비트 맵을 바이트 []로 통과했을 때도 마찬가지입니다.

나는 이것을 따랐다 링크 그리고 그것은 Charme처럼 작동하고 매우 빠릅니다.

package your.packagename

import android.graphics.Bitmap;

public class CommonResources { 
      public static Bitmap photoFinishBitmap = null;
}

내 첫 번째 acitiviy에서 :

Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);

그리고 여기 내 두 번째 활동의 onCreate ()가 있습니다.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bitmap photo = Constants.photoFinishBitmap;
    if (photo != null) {
        mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top