অ্যান্ড্রয়েড: একটি কেন্দ্র বিন্দুতে কীভাবে একটি বিটম্যাপ ঘোরানো যায়


84

আমি এই সমস্যার সমাধানের জন্য একদিন ধরে খুঁজছি কিন্তু কিছুই এখানে সহায়তা করে না, এমনকি এখানে উত্তরও দেয়। ডকুমেন্টেশন খুব কিছুই ব্যাখ্যা করে না।

আমি কেবল অন্য কোনও বস্তুর দিকে ঘোরানোর চেষ্টা করছি। সমস্যাটি হ'ল বিটম্যাপটি একটি নির্দিষ্ট পয়েন্টের আশেপাশে নয়, বরং বিটম্যাপের (0,0) কাছাকাছি ঘোরানো হয়।

এখানে কোডটি নিয়ে আমি সমস্যায় পড়ছি:

  Matrix mtx = new Matrix();
  mtx.reset();
  mtx.preTranslate(-centerX, -centerY);
  mtx.setRotate((float)direction, -centerX, -centerY);
  mtx.postTranslate(pivotX, pivotY);
  Bitmap rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, spriteWidth, spriteHeight, mtx, true);
  this.bitmap = rotatedBMP;

অদ্ভুত অংশটি হ'ল আমি pre/ postTranslate()এবং ভাসমান যুক্তিগুলির মধ্যে মানগুলি কীভাবে পরিবর্তন করি তা বিবেচনা করে না setRotation()। কেউ দয়া করে আমাকে সাহায্য করতে এবং সঠিক দিকে ঠেলে দিতে পারেন? :)


4
আমি এটিকে উপরের কোডটি বিভিন্ন প্রয়াসের বিভিন্ন প্রকারের পরে নিচ্ছি। দেখে মনে হচ্ছে mtx.setRotate (dir, x, y) এর আগে / পোস্টের সমস্ত স্টাফ ছাড়াই নিজেই কৌশলটি করা উচিত। এছাড়াও, আপনাকে নতুনভাবে newএড ম্যাট্রিক্স পুনরায় সেট করার দরকার নেই । এটি ইতিমধ্যে পরিচয়।
মার্ক স্টোর 21

উত্তর:


101

আমি আশা করি নিম্নলিখিত কোডের ক্রমটি আপনাকে সহায়তা করবে:

Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());

আপনি যদি নিম্নলিখিত পদ্ধতিটি পরীক্ষা করে থাকেন তবে ~frameworks\base\graphics\java\android\graphics\Bitmap.java

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
        Matrix m, boolean filter)

এটি ঘূর্ণন এবং অনুবাদ দিয়ে কী করে তা ব্যাখ্যা করবে।


4
আপনি কি এটি ম্যাট্রিক্সের বিটম্যাপ.ক্রেটবিটম্যাপ দিয়ে করতে পারেন? আপনি কীভাবে টার্গেটউইথ এবং টার্গেটহাইটের গণনা করছেন? সরল ট্রিগ, আমি ধরে নিলাম, তবে কি কোনও "সহজ" উপায় আছে?

দয়া করে নীচের উত্তরটি চেক করুন, (দুঃখিত, আমি মন্তব্যে কোড যুক্ত করতে পারিনি)
সুদার নিমালান

এটি প্রয়োগ করার সময় গুণমান খারাপ হয়। কোন সমাধান?
এমএসউডি

4
ক্যানভাস.ড্রেডবিটম্যাপ (উত্স, ম্যাট্রিক্স, নতুন পেইন্ট ()) পরিবর্তন করুন; ক্যানভাস.ড্রেডবিটম্যাপ (উত্স, ম্যাট্রিক্স, নতুন পেইন্ট (পেইন্ট। আন্টি_এলআইএএস_এফএলএজি)) সহ;
সুদার নিমালান

4
কেবল এই মন্তব্যটি যে এই প্রক্রিয়াটি খুব স্মৃতি-ক্ষুধার্ত, এবং পদক্ষেপ পদ্ধতিতে ব্যবহার করা উচিত নয়।
এমএলপ্রোগ্রামার-সিআইএম

79

সম্পাদিত : অনুকূলিত কোড।

public static Bitmap RotateBitmap(Bitmap source, float angle)
{
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);
      return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

সংস্থান থেকে বিটম্যাপ পেতে:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img);

যে কোনও ডাব্লু বা এইচ দিয়ে বিটম্যাপ ঘোরানোর জন্য এটি চেষ্টা করুন: ম্যাট্রিক্স ম্যাট্রিক্স = নতুন ম্যাট্রিক্স (); ম্যাট্রিক্স.পোস্টরোটেট (90); বিটম্যাপপিকচার = বিটম্যাপক্রেটবিটম্যাপ (বিটম্যাপপিকচার, 0, 0, বিটম্যাপপিকচার.জিটভিডথ (), বিটম্যাপপিকচার.জিটহাইট (), ম্যাট্রিক্স, ট্রু)
মার্ক মোলিনা

আমি ইমেজ পয়েন্টগুলির জন্য পরামিতিগুলি নির্ধারণ করায় এটি আমার পক্ষে নিখুঁতভাবে কাজ করেছে। ক্যানভাসে বিটম্যাপ আঁকানোর সময় আপনাকে কেবল ম্যাট্রিক্স ব্যবহার করতে হবে তা নিশ্চিত করতে হবে।
a54 স্টুডিও

6
আপনি কি নিশ্চিত যে এটি দক্ষ? যদি রোটেটবিটম্যাপ () N বার কার্যকর করে এমন একটি সময় ছিল, বিটম্যাপের রেজোলিউশনের উপর নির্ভর করে আপনি অমিত পরিমাণ মেমরির পাশাপাশি সেই সমস্ত নতুন ম্যাট্রিক্স অবজেক্ট বরাদ্দ নষ্ট করতে পারেন।
রায়হান

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

এফওয়াইআই, বিটম্যাপটি পরিবর্তনীয় হতে হবে
কিপ 2

25

আমি এখন এই সমস্যায় ফিরে এসেছি যে আমরা গেমটি চূড়ান্ত করছি এবং আমার পক্ষে কী কাজ করেছে তা পোস্ট করার চিন্তা করেছি thought

ম্যাট্রিক্সকে ঘোরানোর জন্য এই পদ্ধতি:

this.matrix.reset();
this.matrix.setTranslate(this.floatXpos, this.floatYpos);
this.matrix.postRotate((float)this.direction, this.getCenterX(), this.getCenterY()); 

( this.getCenterX()মূলত বিটম্যাপ এক্স অবস্থান + বিটম্যাপ প্রস্থ / 2)

এবং বিটম্যাপ আঁকার জন্য পদ্ধতি (একটি RenderManagerশ্রেণীর মাধ্যমে ডাকা হয় ):

canvas.drawBitmap(this.bitmap, this.matrix, null);

সুতরাং এটি সোজা এগিয়ে রয়েছে তবে আমি এটি অদ্ভুত মনে করি যে এটি setRotateঅনুসরণ করে আমি কাজ করতে পারি না postTranslate। কেউ কেউ জানেন কেন এটি কাজ করে না? এখন সমস্ত বিটম্যাপগুলি সঠিকভাবে আবর্তিত হয় তবে এটি বিটম্যাপ মানের কিছুটা হ্রাস ছাড়াই নয়: /

যাইহোক, আপনার সহায়তার জন্য ধন্যবাদ!


আগের উত্তর কোডটিও কাজ করে। মানের একই সমস্যা সঙ্গে।
এমএসউডি

7

আপনি এটি ImageViewব্যবহার করেও ঘোরান RotateAnimation:

RotateAnimation rotateAnimation = new RotateAnimation(from, to,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(ANIMATION_DURATION);
rotateAnimation.setFillAfter(true);

imageView.startAnimation(rotateAnimation);

4
আপনি ভুল প্রশ্নের উত্তর দিচ্ছেন। তিনি ভিউটি ঘোরাতে চান না, এর মধ্যে কেবল একটি একক বিটম্যাপ।
মার্ক স্টোর

যেমনটি আমি অভিজ্ঞ হয়েছি, সেটফিলএফটার (বুল) পদ্ধতি অ্যান্ড্রয়েড এপিআই lvl 11 এবং তার চেয়ে নীচে প্রত্যাশা মতো কাজ করছে না। অতএব, বিকাশকারীরা দৃশ্য অবজেক্টগুলিতে অবিচ্ছিন্ন ঘূর্ণন ইভেন্ট ব্যবহার করতে অক্ষম, না তারা ঘোরার পরে এই দর্শনগুলির ঘূর্ণিত সংস্করণগুলি গ্রহণ করে। সুতরাং @ মার্ক স্টোরার, ম্যাকার্স যুক্তিযুক্ত দৃষ্টিকোণে সত্যই উত্তর দিয়েছেন যদি আপনি অ্যানিমেশনের সময়কাল 0 বা 0 এর কাছাকাছি কিছু করে সেট করেন
গোখান বারে আখের

5

আপনি নীচের মতো কিছু ব্যবহার করতে পারেন:


Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight());
matrix.mapRect(rectF);
Bitmap targetBitmap = Bitmap.createBitmap(rectF.width(), rectF.height(), config);
Canvas canvas = new Canvas(targetBitmap);
canvas.drawBitmap(source, matrix, new Paint());


সমস্ত সমস্যার জন্য একই সমস্যা: বিটম্যাপ মানের হ্রাস
এমএসএডি

ক্যানভাস.ড্রেডবিটম্যাপ (উত্স, ম্যাট্রিক্স, নতুন পেইন্ট ()) পরিবর্তন করুন; ক্যানভাস.ড্রেডবিটম্যাপ (উত্স, ম্যাট্রিক্স, নতুন পেইন্ট (পেইন্ট। আন্টি_এলআইএএস_এফএলএজি)) সহ;
সুদার নিমালান

আপনি যে কনফিগারটি ব্যবহার করছেন তা কী?
সুদার নিমালান

আমি উত্তর হিসাবে নীচে কোড পোস্ট। মন্তব্য করে এটি লিখতে পারে না। অনেক অনেক ধন্যবাদ স্যার :)
এমএসউডি


1

আমি এই কনফিগারেশনগুলি ব্যবহার করেছি এবং এখনও পিক্সালাইজেশনের সমস্যা আছে:

Bitmap bmpOriginal = BitmapFactory.decodeResource(this.getResources(), R.drawable.map_pin);
        Bitmap targetBitmap = Bitmap.createBitmap((bmpOriginal.getWidth()),
                (bmpOriginal.getHeight()), 
                Bitmap.Config.ARGB_8888);
        Paint p = new Paint();
        p.setAntiAlias(true);

        Matrix matrix = new Matrix();       
        matrix.setRotate((float) lock.getDirection(),(float) (bmpOriginal.getWidth()/2),
                (float)(bmpOriginal.getHeight()/2));

        RectF rectF = new RectF(0, 0, bmpOriginal.getWidth(), bmpOriginal.getHeight());
        matrix.mapRect(rectF);

        targetBitmap = Bitmap.createBitmap((int)rectF.width(), (int)rectF.height(), Bitmap.Config.ARGB_8888);


        Canvas tempCanvas = new Canvas(targetBitmap); 
        tempCanvas.drawBitmap(bmpOriginal, matrix, p);

4
আপনি কি ফিল্টারবিটম্যাপ সেট করতে পারেন, অপশন নির্ধারণ করতে পারেন
সুদার নিমালান

4
হ্যাঁ, এটি পুরোপুরি কাজ করেছে। আপনাকে অনেক ধন্যবাদ সুদার, আপনি আমাকে সত্যিই অনেক সাহায্য করেছেন।
এমএসউডি

4
আপডেট করা কোডের সাথে আপনার নিজের ফলোআপে লিঙ্ক যুক্ত করা হচ্ছে: stackoverflow.com/questions/13048953/…
ক্রিস রায়

0
matrix.reset();
matrix.setTranslate( anchor.x, anchor.y );
matrix.postRotate((float) rotation , 0,0);
matrix.postTranslate(positionOfAnchor.x, positionOfAnchor.x);
c.drawBitmap(bitmap, matrix, null); 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.