আপনি কীভাবে একটি বাফার্ডআইমেজ ক্লোন করবেন?


120

আমার একটি অবজেক্ট রয়েছে যার এতে অনেকগুলি বফেরিমেজ রয়েছে, আমি নতুন বাজেটে সমস্ত বাফারডেমেজগুলি অনুলিপি করে একটি নতুন অবজেক্ট তৈরি করতে চাই, তবে এই নতুন চিত্রগুলি পরিবর্তিত হতে পারে এবং আমি চাই না যে মূল অবজেক্টের চিত্রগুলি পরিবর্তন করে পরিবর্তন করা হোক নতুন বস্তু ইমেজ।

ঠিক আছ?

এটি করা কি সম্ভব এবং কেউ দয়া করে এটি করার জন্য কোনও ভাল উপায়ের পরামর্শ দিতে পারেন? আমি getSubImage সম্পর্কে চিন্তা করেছি তবে কোথাও পড়েছি যে সাবাইমেজে কোনও পরিবর্তন প্যারেন্ট চিত্রটিতে ফিরে আসে।

আমি কেবল একটি নতুনভাবে সম্পূর্ণ আলাদা অনুলিপি বা একটি বাফারডিমেজের ক্লোন পেতে সক্ষম হতে চাই


1
আপনি কি clone()পদ্ধতি কল করতে পারবেন না ? নাকি আমি কিছু মিস করেছি? BufferedImageক্লাস সম্পর্কে আমি খুব বেশি কিছু জানি না
নোয়েল এম

1
ক্লোনটি কেবল একটি অগভীর অনুলিপি সরবরাহ করে যাতে এতে বাফার করা চিত্রগুলির উল্লেখ থাকতে পারে; তাদের অনুলিপি না।
চূড়ান্ত গোব্লেমেন্ট

7
@ নোয়েলএম, আলটিমেট ગોব্লেমেন্ট: BufferedImageকার্যকর হয় না Cloneableএবং clone()পদ্ধতিটি অ্যাক্সেস সুরক্ষিত করে।
রবার্ট

উত্তর:


173

এটার মতো কিছু?

static BufferedImage deepCopy(BufferedImage bi) {
 ColorModel cm = bi.getColorModel();
 boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
 WritableRaster raster = bi.copyData(null);
 return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}

4
আমি আমার প্রোগ্রামে এটিও ধার করছি =)
ড্যানিয়েল কেটস

সাবমিজেজ অনুলিপি করার জন্য এই পদ্ধতিটি নিয়ে সমস্যা আছে
মিশক

7
যদিও এটি বেশিরভাগ পরিস্থিতিতে কাজ করে, যখন সেই বাফারডিমেজটি ক্রপ করা হয়েছিল তখন এটি সঠিকভাবে কাজ করে না (এটি পুরো চিত্রটি ফসলের আগে ফেরত দেয়)।
এটির

3
নতুন বাফারডেমেজ (সেন্টিমিটার, রাস্টার, ইল্ফাপ্রিম্টিপ্লাইটিড, নাল) ফিরে দিন get বিটসুবিমেজ (0, 0, bi.getWidth (), bi.getHeight ());
হেডেনস্টুডিওগুলি

কপিডাটা (নাল) সর্বদা কাজ করে না কারণ এটি পিতামহীন রাস্টার উপর কাজ করতে পারে (যেমন, যখন চিত্রটি উপ চিত্র হয়), আমার পরিবর্তিত উত্তর দেখুন
ব্যবহারকারী 1050755

46

আমি এই কাজ:

public static BufferedImage copyImage(BufferedImage source){
    BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
    Graphics g = b.getGraphics();
    g.drawImage(source, 0, 0, null);
    g.dispose();
    return b;
}

এটি মোটামুটি ভাল কাজ করে এবং এটি ব্যবহার করা সহজ।


3
এটি দেখতে বেশ সহজ দেখাচ্ছে। কেন এটি সেরা উত্তর নয়? এমন কোনও ত্রুটি আছে যা সম্পর্কে আমি অবগত নই?
WVrock

2
@WRrock চিত্রের ধরণ 0 (কাস্টম) হয় তবে এটি কাজ করে না
তিলমান হাশার

3
গ্রাফিক্স প্রতিস্থাপন g = b.getGraphics (); গ্রাফিক্স 2 ডি দ্বারা g = b.createGraphics (); এবং এটি নিখুঁত
নাদির

1
আমি মনে করি এটিই সবচেয়ে পরিষ্কার উত্তর। যদিও এটি এবং গৃহীত উত্তরের মধ্যে কোনও পারফরম্যান্সের পার্থক্য রয়েছে? নাহলে আমার মনে হয় যদি না হয়? এটি কি আর দ্রুত হতে পারে কারণ জেভিএমে অবজেক্টের সৃষ্টিটি অনুকূলিত হয়েছে। ওপেনড্যাডক ১১ ব্যবহার করাও যদি কেউ এই প্রশ্নের উত্তর দিতে পারে।
thekevshow

18

পূর্বে উল্লিখিত পদ্ধতিটি সাব চিত্রগুলিতে প্রয়োগ করার সময় ব্যর্থ হয়। এখানে আরও একটি সম্পূর্ণ সমাধান:

public static BufferedImage deepCopy(BufferedImage bi) {
    ColorModel cm = bi.getColorModel();
    boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
    WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster());
    return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}

আপনাকে ধন্যবাদ, আমি একটি সাবিমেজ ক্লোন করার চেষ্টা করে একটি অফসেট ত্রুটি পেয়েছিলাম। এই সংস্করণটি ঠিক আমার যা প্রয়োজন তা হ'ল।
rococo

5

Graphics2Dনতুন উপায়টি হল একটি নতুন ফাঁকা চিত্রের উপর চিত্র আঁকতে শ্রেণিটি ব্যবহার করা । এটি চিত্রটির সত্যই ক্লোন করে না, তবে এটি চিত্রটির একটি অনুলিপি তৈরির ফলস্বরূপ।

public static final BufferedImage clone(BufferedImage image) {
    BufferedImage clone = new BufferedImage(image.getWidth(),
            image.getHeight(), image.getType());
    Graphics2D g2d = clone.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    return clone;
}

4

ক্লাস বাফার্ডআইমেজ ক্লোনযোগ্য ইন্টারফেস প্রয়োগ করে না। সুতরাং ক্লোন পদ্ধতিটি ওভাররেড করা হয় না। গভীর অনুলিপি কৌশলটির জন্য এখানে একটি বিকল্প রয়েছে: জাভা টিপ 76: গভীর অনুলিপি কৌশলটির একটি বিকল্প


4

আমি জানি যে এই প্রশ্নটি বেশ পুরানো, তবে ভবিষ্যতের দর্শকদের জন্য, আমি যে সমাধানটি ব্যবহার করব তা এখানে:

Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);

দয়া করে আমাকে সংশোধন করুন যদি সদ্য প্রাপ্ত পরিবর্তনটি কোনওভাবেই newImageমূল চিত্রটিকে প্রভাবিত করে।
-> স্ক্যাসাইলড ইনস্ট্যান্সের জন্য জাভাডোক
-> এসসিএএল_ডিএফএলএটি -এর জাভাডোক (অন্যান্য ধ্রুবকগুলির ঠিক নীচে তালিকাভুক্ত করা হয়েছে)


আমি মনে করি এটি আসলে চিত্রটি অনুলিপি করবে না, অর্থাত্ যদি আপনি স্কেলড উইলালসো পরিবর্তনটি মূলটি পরিবর্তন করেন তবে এটি এতক্ষণ অসুস্থ হয়ে গিয়েছিল যাতে অন্য কেউ নিশ্চিতভাবে বলতে পারে।
f1wade

1
এটি প্রকৃতপক্ষে চিত্রটির অনুলিপি করে, মূল পরিবর্তনে অনুলিপিটি পরিবর্তন হয় না। এই উত্তরটি সংক্ষিপ্ত এবং সংক্ষিপ্ত এবং এমনকি বাফার্ডআইমেজগুলির মধ্যে সীমাবদ্ধ নয়। একমাত্র ইস্যুটি এটি ফিরে আসে Image, না BufferedImage
ক্রু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.