উত্তর:
Bitmap
প্রয়োগ Parcelable
, যাতে আপনি সর্বদা এটি অভিপ্রায় সহ পাস করতে পারেন:
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
এবং অন্য প্রান্তে এটি পুনরুদ্ধার করুন:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
প্রকৃতপক্ষে, পার্সলেবল হিসাবে একটি বিটম্যাপটি পাস করার ফলে "জাভা বাইন্ডার ব্যর্থতা" ত্রুটি হবে। বাইট অ্যারে হিসাবে বিটম্যাপটি পাস করার চেষ্টা করুন এবং পরবর্তী ক্রিয়াকলাপে এটি প্রদর্শনের জন্য তৈরি করুন।
আমি এখানে আমার সমাধানটি ভাগ করেছি: আপনি
কীভাবে বান্ডিলগুলি ব্যবহার করে অ্যান্ড্রয়েড ক্রিয়াকলাপগুলির মধ্যে চিত্রগুলি (বিটম্যাপস) পাস করবেন?
পার্সেবল (1 মিমি) আকারের সীমাবদ্ধতার কারণে ক্রিয়াকলাপের মধ্যে বান্ডলে পার্টেবল হিসাবে বিটম্যাপটি উত্তোলন করা ভাল ধারণা নয়। আপনি অভ্যন্তরীণ স্টোরেজে কোনও ফাইলে বিটম্যাপ সংরক্ষণ করতে পারেন এবং বেশ কয়েকটি ক্রিয়াকলাপে সঞ্চিত বিটম্যাপটি পুনরুদ্ধার করতে পারেন। এখানে কিছু নমুনা কোড।
অভ্যন্তরীণ স্টোরেজে আমার আইমেজ ফাইলটিতে বিটম্যাপ সংরক্ষণ করতে:
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;
}
তারপরে পরবর্তী ক্রিয়াকলাপে আপনি এই কোডটি মাই ইমেজটি নীচের কোডটি ব্যবহার করে একটি বিটম্যাপে ডিকোড করতে পারেন:
//here context can be anything like getActivity() for fragment, this or MainActivity.this
Bitmap bitmap = BitmapFactory.decodeStream(context.openFileInput("myImage"));
দ্রষ্টব্য নাল এবং স্কেলিং বিটম্যাপের জন্য প্রচুর চেক করা বাদ দেওয়া হয়েছে।
openFileOutput
।
চিত্রটি যদি খুব বড় হয় এবং আপনি এটি স্টোরেজে সঞ্চয় করতে এবং লোড করতে না পারেন, তবে আপনাকে কেবল বিটম্যাপের (প্রাপ্ত ক্রিয়াকলাপের অভ্যন্তরে) একটি বিশ্বব্যাপী স্ট্যাটিক রেফারেন্স ব্যবহার করা উচিত, যা কেবলমাত্র "isChangingConfigurations" হলেই onDestory এ বাতিল হয়ে যাবে reset সত্য ফিরে।
কারণ ইন্টেন্টের আকারের সীমা রয়েছে। আমি পরিষেবা থেকে সম্প্রচারে বিটম্যাপ পাস করতে সর্বজনীন স্ট্যাটিক অবজেক্ট ব্যবহার করি ....
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, একটি দ্বারা প্রতিনিধিত্ব ByteArray
, তাহলে এটি নিরাপদে কোনও মাধ্যমে প্রেরণ করা সম্ভবIntent
।
ফাংশনটি কোটলিন Coroutines ব্যবহার করে একটি পৃথক থ্রেডে অন্তর্ভুক্ত কারণ একটি ইউআরএল থেকে তৈরি Bitmap
হওয়ার পরে সংকোচনের শৃঙ্খলাবদ্ধ । সৃষ্টি এড়াতে অনুক্রমে একটি পৃথক থ্রেডে প্রয়োজন APPLICATION সাড়া দিচ্ছে না (ANR- এর) ত্রুটি।Bitmap
String
Bitmap
toBitmap()
একটি হল Kotlin এক্সটেনশন ফাংশন লাইব্রেরির প্রয়োজন অ্যাপ্লিকেশন নির্ভরতা যোগ করা হবে।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.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
ত্রুটি উত্পন্ন করে 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()));
আমার ক্ষেত্রে, উপরে উল্লিখিত পদ্ধতিটি আমার পক্ষে কার্যকর হয়নি। আমি যতবার বিটম্যাপটি অভিপ্রায় রেখেছি, ততবার দ্বিতীয় ক্রিয়াকলাপটি শুরু হয়নি। আমি যখন বাইট হিসাবে বিটম্যাপটি পাস করেছি তখন একই ঘটনা ঘটে []।
আমি এই লিঙ্কটি অনুসরণ করেছি এবং এটি একটি আকর্ষণীয় এবং খুব দ্রুত কাজ করেছে:
package your.packagename
import android.graphics.Bitmap;
public class CommonResources {
public static Bitmap photoFinishBitmap = null;
}
আমার 1 ম অ্যাকটিভিয়ায়:
Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);
এবং এখানে আমার দ্বিতীয় ক্রিয়াকলাপের অনক্রিট () রয়েছে:
@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
বিটম্যাপ বিটম্যাপ নিজেই এবং। পুরো বিটম্যাপটি পাস করার জন্য প্রচুর স্মৃতি দরকার। ইউআরএল পাস করার জন্য খুব অল্প স্মৃতি দরকার এবং প্রতিটি ক্রিয়াকলাপটি যেমন প্রয়োজন তেমন বিটম্যাপটি লোড করতে এবং স্কেল করতে দেয়।