2013-08-14 2 views
7

पर बिटमैप छवि को फीका करें मैं एक कैनवास पर स्केल किए गए बिटमैप को चित्रित कर रहा हूं और एक निश्चित समय पर अपनी छवि को फीका करना चाहता हूं।एंड्रॉइड - कैनवास

असल में, जब मेरी चरित्र छवि कैनवास के एक निश्चित खंड पर जाती है, तो मुझे पृष्ठ को धीरे-धीरे अगले जावा क्लास में फिर से निर्देशित करने से पहले चरित्र छवि को धीरे-धीरे फीका (3 सेकंड) की आवश्यकता होती है।

वर्तमान में, मेरी छवि बस नए जावा क्लास पर रीडायरेक्ट हो जाती है, कृपया नीचे दी गई छवि देखें कि मैं अपनी छवि कैसे बना रहा हूं।

Resources res = getResources(); 
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, res.getDisplayMetrics()); 
imgSpacing = (int) px/2; 
int size = (int) ((PhoneWidth/5) - px); 

chrImg = BitmapFactory.decodeResource(getResources(), R.drawable.character); 
chrImg = Bitmap.createScaledBitmap(chrImg, size, size, true); 

तो कैनवास OnDraw भीतर:

if(indexX == mazeFinishX && indexY == mazeFinishY) 
{ 
    canvas.drawBitmap(finish, j * totalCellWidth, i * totalCellHeight, null); 
    // As soon as the character moves over this square they are automatically re-directed to new page 
    // This is where I want to fade the character image out before the re-direct 
} 

मैं ऑनलाइन देखा है, लेकिन काफी बाहर काम नहीं कर सकता कि मेरे drawable मेरे खेल संसाधनों drawable फ़ोल्डर से प्राप्त किए गए छवि के लिए काम करने के लिए fading मिलता है। धन्यवाद

उत्तर

8

यदि आपको लगता है कि आप संभावना है कि आप सड़क के नीचे फीका एनीमेशन बदलना चाहते हैं, जैसे स्केलिंग और/या घूर्णन करना, तो आपको एनीमेशन एक्सएमएल के साथ जाना चाहिए।

लेकिन केवल एक त्वरित बिटमैप फीका के लिए, आप बार-बार अमान्यता संदेशों को देरी कर सकते हैं।आप शायद अपने अवैध क्षेत्र सीमित करने के लिए बस जहां के लिए अपने चरित्र बिटमैप है चाहता हूँ:

private static final int FADE_MILLISECONDS = 3000; // 3 second fade effect 
private static final int FADE_STEP = 120;   // 120ms refresh 

// Calculate our alpha step from our fade parameters 
private static final int ALPHA_STEP = 255/(FADE_MILLISECONDS/FADE_STEP); 

// Initializes the alpha to 255 
private Paint alphaPaint = new Paint(); 

// Need to keep track of the current alpha value 
private int currentAlpha = 255; 

@Override 
protected void onDraw(Canvas canvas) { 
    ... 
    if(indexX == mazeFinishX && indexY == mazeFinishY) { 

     // Drawing your wormhole? 
     int x = j * totalCellWidth; 
     int y = i * totalCellHeight; 
     canvas.drawBitmap(finish, x, y, null); 

     if (currentAlpha > 0) { 

      // Draw your character at the current alpha value 
      canvas.drawBitmap(chrImg, x, y, alphaPaint); 

      // Update your alpha by a step 
      alphaPaint.setAlpha(currentAlpha); 
      currentAlpha -= ALPHA_STEP; 

      // Assuming you hold on to the size from your createScaledBitmap call 
      postInvalidateDelayed(FADE_STEP, x, y, x + size, y + size); 

     } else { 
      // No character draw, just reset your alpha paint 
      currentAlpha = 255; 
      alphaPaint.setAlpha(currentAlpha); 

      // Now do your redirect 
     } 
    } 
    ... 
} 

मैं में रेस/integers.xml स्थिरांक FADE_MILLISECONDS और FADE_STEP डाल सिर्फ इसलिए वे हार्ड-कोडेड नहीं कर रहे हैं सलाह देते हैं।

+0

मैंने आपके उपरोक्त कोड को लागू किया है और लुप्तप्राय सही तरीके से काम कर रहा है। हालांकि यहां मुद्दा यह तथ्य है कि मेरा पुनः निर्देश काम नहीं कर रहा है। यह रीडायरेक्ट कोड के साथ फ़ंक्शन को हिट करता है, हालांकि इसे किसी भी विचार को अनदेखा करना प्रतीत होता है? –

+0

मैंने एक "currentAlpha" फ़ील्ड जोड़ा, setAlpha/getAlpha का उपयोग करके शायद 1 के अल्फा चरण के अलावा किसी अन्य चीज़ के साथ काम नहीं कर रहा था। –

1
 if(indexX == mazeFinishX && indexY == mazeFinishY) 
     { 
      canvas.drawBitmap(finish, j * totalCellWidth, i * totalCellHeight, null); 
      // As soon as the character moves over this square they are automtically re-directs to new page 
      new CountDownTimer(0500, 1000) { 
       @Override 
       public void onTick(long millisUntilFinished) {} 
       @Override 
       public void onFinish() { 
Paint paint = new Paint(); 
paint.setAlpha(25); 
canvas.drawBitmap(chrImg, 0, 0, paint); 
       } 
      }.start(); 
      new CountDownTimer(0500, 1000) { 
       @Override 
       public void onTick(long millisUntilFinished) {} 
       @Override 
       public void onFinish() { 
Paint paint = new Paint(); 
paint.setAlpha(45); 
canvas.drawBitmap(chrImg, 0, 0, paint);    } 
      }.start(); 
      new CountDownTimer(0500, 1000) { 
       @Override 
       public void onTick(long millisUntilFinished) {} 
       @Override 
       public void onFinish() { 
Paint paint = new Paint(); 
paint.setAlpha(70); 
canvas.drawBitmap(chrImg, 0, 0, paint);    } 
      }.start(); 
      new CountDownTimer(0500, 1000) { 
       @Override 
       public void onTick(long millisUntilFinished) {} 
       @Override 
       public void onFinish() { 
Paint paint = new Paint(); 
paint.setAlpha(100); 
canvas.drawBitmap(chrImg, 0, 0, paint);    } 
      }.start(); 
      // This is where I want to fade the cahracter image out before the re-direct 
      new CountDownTimer(3000, 1000) { 

      @Override 
      public void onTick(long millisUntilFinished) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onFinish() { 
       // TODO Auto-generated method stub 

        Intent i = new Intent(currentclass.this, nextClass.class); 
        startActivity(i); 
      } 
     }.start(); 

    } 

इससे आपका बिटमैप पारदर्शी हो जाएगा (अल्फा 100 होगा) .. और उसके बाद 3 सेकंड के बाद अगली कक्षा में रीडायरेक्ट करें।

अद्यतन: बिटमैप आप .setAlpha उपयोग नहीं कर सकते हैं तो हम एक पेंट का उपयोग करना चाहिए के लिए , तो हम एक नया रंग हर बार तो पेंट के साथ बिटमैप सेट बनाया। लेकिन अगर आपके पास एक छवि दृश्य है तो आप .setalpha

+0

यह रीडायरेक्ट में देरी में काम करता है, हालांकि मैं इसे बनाना चाहता हूं ताकि छवि धीरे-धीरे दूर हो जाए। अनिवार्य रूप से, मेरे पास एक कीड़ा छेद छवि है और एनीमेशन पर कुछ प्रकार के माध्यम से चरित्र छवि गायब हो जाना चाहती है (मैं छवि को दूर करने में सोच रहा था)। –

+0

बस आपके कोड को आजमाया, हालांकि एहसास हुआ कि चूंकि यह ड्रॉबल संसाधनों से बिटमैप है, इसलिए आप setAlpha का उपयोग नहीं कर सकते हैं। क्या कोई और तरीका है, कृपया छवि को दोहराने के लिए मेरा मूल कोड देखें। –

+0

मैंने कोड अपडेट किया है, इसे अभी जांचें। –

3

यह समझाने के लिए मेरे लिए सबसे अच्छा तरीका एक पूर्ण कस्टम दृश्य उदाहरण प्रदान करता है कि आप जिस टुकड़े की जरूरत है उसे खींच सकते हैं। नीचे एक ऐसा दृश्य है जो इसे पूरा करता है।

public class CharacterView extends View { 

    private Paint mCharacterPaint; 
    private Bitmap mCharacterBitmap; 
    private Transformation mTransformation; 
    private AlphaAnimation mFadeOut; 

    public CharacterView(Context context) { 
     super(context); 
     init(context); 
    } 

    public CharacterView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context); 
    } 

    public CharacterView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(context); 
    } 

    private void init(Context context) { 
     //This would be your character image instead 
     mCharacterBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 

     //We need a paint to efficiently modify the alpha 
     mCharacterPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     //This is needed to house the current value during the animation 
     mTransformation = new Transformation(); 
     //Construct an animation that will do all the timing math for you 
     mFadeOut = new AlphaAnimation(1f, 0f); 
     mFadeOut.setDuration(500); 
     //Use a listener to trigger the end action 
     mFadeOut.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       //Trigger your action to change screens here. 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { } 
     }); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      //In this example, touching the view triggers the animation 
      // your code would run this sequence when the character reaches the 
      // appropriate coordinates (P.S. I would not advocate putting this code 
      // inside of onDraw() 
      mFadeOut.start(); 
      mFadeOut.getTransformation(System.currentTimeMillis(), mTransformation); 
      invalidate(); 
     } 
     return true; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     //...existing drawing code... 

     canvas.drawBitmap(mCharacterBitmap, 0, 0, mCharacterPaint); 
     if (mFadeOut.hasStarted() && !mFadeOut.hasEnded()) { 
      mFadeOut.getTransformation(System.currentTimeMillis(), mTransformation); 
      //Keep drawing until we are done 
      mCharacterPaint.setAlpha((int)(255 * mTransformation.getAlpha())); 
      invalidate(); 
     } else { 
      //Reset the alpha if animation is canceled 
      mCharacterPaint.setAlpha(255); 
     } 
    } 
} 

लिए सबसे कारगर तरीका गतिशील तुम क्या आकर्षित की पारदर्शिता को संशोधित करने के लिए यह एक Paint अपने Canvas को ड्राइंग का उपयोग कर लागू करने के लिए है। चरित्र को समाप्त होने तक एनीमेशन प्रदर्शित करने के लिए आपको प्रत्येक फ्रेम संक्रमण के साथ लगातार invalidate() दृश्य की आवश्यकता होगी। उदाहरण एनीमेशन वास्तव में अच्छा दिखने के लिए सभी समय गणित को संभालने के लिए Animation ऑब्जेक्ट और Transformation ऑब्जेक्ट का उपयोग करता है।

यहां बताया गया है कि आप कुछ बाहरी ट्रिगर के माध्यम से एनीमेशन शुरू करते हैं (मैं onDraw() में फीका होने के लिए चेक करने की अनुशंसा नहीं करता, शायद उस स्थान पर बेहतर जहां उन चरित्र स्थानों को अपडेट किया गया है। मेरे उदाहरण में, सादगी के लिए, मैं छुआ को यह जब दृश्य शुरू कर दिया।

यह ट्रिगर एनीमेशन शुरू होता है और प्रारंभिक परिवर्तन मूल्य हो जाता है, तो invalidate() एक नया onDraw() से चलाता है। एनीमेशन चल रहा हो, onDraw()invalidate() की वजह से दोहराया है और प्रत्येक पुनरावृत्ति पेंट पर अल्फा थोड़ा कम हो जाता है।

जब एनीमेशन समाप्त हो जाता है, तो यह आपके लिए AnimationListener पर कॉल करेगा, ताकि आप onAnimationEnd() के अंदर स्क्रीन संक्रमण को ट्रिगर कर सकें।

+0

आपको केवल उस क्षेत्र को अमान्य करना चाहिए जहां चरित्र को फिर से खींचा जा रहा है। –

+0

यदि समग्र दृश्य बड़ा है तो यह एक अच्छा अनुकूलन हो सकता है। हालांकि कई आम मामलों में (जैसे हार्डवेयर त्वरण सक्षम) गंदे रीक्ट्स को वास्तव में अनदेखा कर दिया जाता है; तो यह आमतौर पर प्रदर्शन वारंट तक शामिल करने के प्रयास के लायक नहीं है। – Devunwired

+0

एंड्रॉइड डेवलपर्स में से एक का यह जवाब आपके दावे का खंडन करता है कि हार्डवेयर त्वरण गंदे क्षेत्रों को अनदेखा करता है: http://stackoverflow.com/questions/7233830/partial-invalidation-in-custom-android-view-with-hardware-acceleration –

संबंधित मुद्दे