답변:
Bitmap
구현 Parcelable
하여 항상 의도와 함께 전달할 수 있습니다.
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
다른 쪽 끝에서 검색하십시오.
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
실제로 비트 맵을 Parcelable로 전달하면 "JAVA BINDER FAILURE"오류가 발생합니다. 비트 맵을 바이트 배열로 전달하고 다음 액티비티에서 표시 할 수 있도록 빌드하십시오.
내 솔루션을 여기에서 공유했습니다 :
번들을 사용하여 안드로이드 활동간에 이미지 (비트 맵)를 어떻게 전달합니까?
Parceable (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 및 스케일링 비트 맵을 많이 검사하지 않아도됩니다.
openFileOutput
.
의도에는 크기 제한이 있기 때문입니다. 공용 정적 객체를 사용하여 서비스에서 브로드 캐스트로 비트 맵을 전달합니다 ....
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
이 너무 크면 허용되는 답변이 중단됩니다 . 나는 그것이 1MB 제한 이라고 생각합니다 . 가 Bitmap
같은 같은 다른 파일 포맷으로 압축되어야 JPG a로 나타내어 ByteArray
, 그것은 안전하게 통해 전달 될 수있다Intent
.
이 함수는 Kotlin Coroutines를 사용하여 별도의 스레드에 포함되어 있습니다. Bitmap
압축은 Bitmap
url에서 작성된 후에 압축 되기 때문 String
입니다. Bitmap
창조 회피하기 위해 별도의 스레드가 필요합니다 응용 프로그램 (ANR) 응답 없음 오류를.
toBitmap()
A는 코 틀린 확장 기능 이 라이브러리를 요구 앱 종속성에 첨가한다.Bitmap
을 JPG는 ByteArray
그것이 생성 된 후에.Repository.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}")
}
}
})
}
ByteArray
통해 이미지를 전달하십시오 Intent
.이 샘플에서는 Fragment 에서 Service로 전달되었습니다 . 두 활동 간에 공유되는 경우 동일한 개념 입니다.
Fragment.kt
ContextCompat.startForegroundService(
context!!,
Intent(context, AudioService::class.java).apply {
action = CONTENT_SELECTED_ACTION
putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
})
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;
도움이 되길 바랍니다.
위의 모든 솔루션이 작동하지 않습니다 . 비트 맵을 전송 parceableByteArray
하면 error 생성됩니다 android.os.TransactionTooLargeException: data parcel size
.
해결책
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;
}
putExtra(String)
로Intent intent = new Intent(ActivitySketcher.this,ActivityEditor.class);
intent.putExtra("KEY", saveBitmap(bmp));
startActivity(intent);
if(getIntent() != null){
try {
src = BitmapFactory.decodeStream(openFileInput("myImage"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
비트 맵 전송을 만들 수 있습니다. 이 시도....
첫 번째 수업에서 :
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()));
내 경우에는 위에서 언급 한 방식이 효과가 없었습니다. 비트 맵을 의도에 넣을 때마다 두 번째 활동이 시작되지 않았습니다. 비트 맵을 byte []로 전달할 때도 마찬가지입니다.
나는이 링크를 따라 갔으며 그것은 매력적이고 매우 빠르게 작동했습니다.
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));
}
}
CommonResources.photoFinishBitmap
대신 대신 사용 했어야합니다 Constants.photoFinishBitmap
.
URI
또는ResourceID
비트 맵 자체 비트 맵의하지를. 전체 비트 맵을 전달하려면 많은 메모리가 필요합니다. URL을 전달하면 메모리가 거의 필요하지 않으며 각 활동이 필요에 따라 비트 맵을로드하고 확장 할 수 있습니다.