2013-04-24 7 views
16

मैं सिर्फ इस कोड के टुकड़े को साझा करना चाहता हूं जिसे मैंने लिखा था। मैंने एक कस्टम फसल गतिविधि की खोज करने की कोशिश की, लेकिन उनमें से अधिकतर सवाल कस्टम फसल, या फ्रीहैंड फसल गतिविधि के बावजूद डिफ़ॉल्ट "com.android.camera.action.CROP" की ओर जाता है। वैसे भी, मैंने अभी खुद के लिए एक बनाया है, और उम्मीद है कि यह आपको लोगों की मदद करेगा।कस्टम एंड्रॉइड छवि फसल

public class CropView extends ImageView { 

    Paint paint = new Paint(); 
    private int initial_size = 300; 
    private static Point leftTop, rightBottom, center, previous; 

    private static final int DRAG= 0; 
    private static final int LEFT= 1; 
    private static final int TOP= 2; 
    private static final int RIGHT= 3; 
    private static final int BOTTOM= 4; 

    private int imageScaledWidth,imageScaledHeight; 
    // Adding parent class constructors 
    public CropView(Context context) { 
     super(context); 
     initCropView(); 
    } 

    public CropView(Context context, AttributeSet attrs) { 
     super(context, attrs, 0); 
     initCropView(); 
    } 

    public CropView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     initCropView(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 
     super.onDraw(canvas); 
     if(leftTop.equals(0, 0)) 
      resetPoints(); 
     canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     int eventaction = event.getAction(); 
     switch (eventaction) { 
      case MotionEvent.ACTION_DOWN: 
       previous.set((int)event.getX(), (int)event.getY()); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if(isActionInsideRectangle(event.getX(), event.getY())) { 
        adjustRectangle((int)event.getX(), (int)event.getY()); 
        invalidate(); // redraw rectangle 
        previous.set((int)event.getX(), (int)event.getY()); 
       } 
       break; 
      case MotionEvent.ACTION_UP: 
       previous = new Point(); 
       break; 
     }   
     return true; 
    } 

    private void initCropView() { 
     paint.setColor(Color.YELLOW); 
     paint.setStyle(Style.STROKE); 
     paint.setStrokeWidth(5); 
     leftTop = new Point(); 
     rightBottom = new Point(); 
     center = new Point(); 
     previous = new Point(); 
    } 

    public void resetPoints() { 
     center.set(getWidth()/2, getHeight()/2); 
     leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2); 
     rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size); 
    } 

    private static boolean isActionInsideRectangle(float x, float y) { 
     int buffer = 10; 
     return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false; 
    } 

    private boolean isInImageRange(PointF point) { 
     // Get image matrix values and place them in an array 
     float[] f = new float[9]; 
     getImageMatrix().getValues(f); 

     // Calculate the scaled dimensions 
     imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]); 
     imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]); 

     return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false; 
    } 

    private void adjustRectangle(int x, int y) { 
     int movement; 
     switch(getAffectedSide(x,y)) { 
      case LEFT: 
       movement = x-leftTop.x; 
       if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) 
        leftTop.set(leftTop.x+movement,leftTop.y+movement); 
       break; 
      case TOP: 
       movement = y-leftTop.y; 
       if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) 
        leftTop.set(leftTop.x+movement,leftTop.y+movement); 
       break; 
      case RIGHT: 
       movement = x-rightBottom.x; 
       if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) 
        rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); 
       break; 
      case BOTTOM: 
       movement = y-rightBottom.y; 
       if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) 
        rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); 
       break;  
      case DRAG: 
       movement = x-previous.x; 
       int movementY = y-previous.y; 
       if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) { 
        leftTop.set(leftTop.x+movement,leftTop.y+movementY); 
        rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY); 
       } 
       break; 
     } 
    } 

    private static int getAffectedSide(float x, float y) { 
     int buffer = 10; 
     if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer)) 
      return LEFT; 
     else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer)) 
      return TOP; 
     else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer)) 
      return RIGHT; 
     else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer)) 
      return BOTTOM; 
     else 
      return DRAG; 
    } 

    public byte[] getCroppedImage() { 
     BitmapDrawable drawable = (BitmapDrawable)getDrawable(); 
     float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2); 
     float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2); 
     Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y); 
     ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
     cropped.compress(Bitmap.CompressFormat.PNG, 100, stream); 
     return stream.toByteArray(); 
    } 
} 

मैंने जो किया, मैंने छवि दृश्य और विस्तारित फसल शक्तियों को बढ़ाया। इसका उपयोग करना बहुत आसान है। एक बार कक्षा सहेजी जाने के बाद, इसे इस तरह के लेआउट में उपयोग करें।

<"your package name".CropView 
     android:id="@+id/image_preview" 
     android:layout_width="fill_parent" 
     android:layout_height="match_parent" /> 

यह बात है! आशा करता हूँ की ये काम करेगा! आप किसी भी समस्या आती है, :)

+0

मैंने उपरोक्त कोड का उपयोग किया, लेकिन फसल की छवि सही ढंग से नहीं मिल रही है, यह ज़ूम हो रहा है। – Santosh

+0

वही समस्या यह आयत की सीमाओं के भीतर छवि को फसल नहीं करती है। यह कुछ कैसे ज़ूम करता है। मैंने @TheHippo जवाब अभी भी एक ही समस्या का प्रयास किया। – Hasham

+0

लेकिन थे मैं इस कोड <: आईडी = "@ + id/image_preview" एंड्रॉयड: layout_width = "fill_parent" एंड्रॉयड layout_height = "match_parent"/"अपने पैकेज का नाम" .CropView एंड्रॉयड> रखना चाहिए वास्तव में आप इस कस्टम फसल को एक छविदृश्य के साथ कैसे कार्यान्वित करते हैं। आप एक कस्टम फसल नहीं ढूंढ सकते जो ImageView को बढ़ाता है। हालांकि, एक बात है, क्या आपको फसल आयताकार पैमाने को आसान बनाने का कोई तरीका मिला है? – Matthew

उत्तर

2

आप प्रयास करना चाहिए:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.crop_layout); 


    myCropView = new CropView(this); 

    Uri imageUri = getIntent().getExtras().getParcelable("path"); 

    b = (BitmapDrawable) BitmapDrawable.createFromPath(imageUri.getPath()); 

    myCropView.setImageURI(imageUri); 
} 

(आपके प्रश्न का संपादित से लिया।)

+2

'बी = (बिटमैप ड्रावेबल) बिटमैप ड्रावेबल.क्रेट फ्रॉमपाथ (imageUri.getPath()) का उपयोग क्या है;' ?? – xmen

+0

@the हिप्पो मैं अपनी सक्रियता में कैसे उपयोग कर सकता हूं – Matthew

0

धन्यवाद thehippo पूछने में संकोच न करें ... लेकिन मैं लेआउट

Uri imageUri = getIntent().getExtras().getParcelable("path"); 
    b = (BitmapDrawable) BitmapDrawable.createFromPath(getRealPathFromURI(imageUri)); 
    myCropView = (CropView) findViewById(R.id.image_preview); 
    myCropView.setBackground(b); 

द्वारा दृश्य खोजने हल है, लेकिन अब मैं स्पर्श घटना को संभाल नहीं कर सकते हैं । आयताकार तब भी रहता है जब मैं स्क्रीन को छूता हूं ...

संपादित करें: ठीक है, मैंने इसे काम किया है। लेकिन अब, आयताकार केवल एक छोटे से क्षेत्र के अंदर चलता है, न कि पूरी छवि में। मुझे लगता है कि वहाँ कुछ यहाँ गलत

private boolean isInImageRange(PointF point) { 
    // Get image matrix values and place them in an array 
    float[] f = new float[9]; 
    getImageMatrix().getValues(f); 

    // Calculate the scaled dimensions 
    imageScaledWidth = Math.round(getBackground().getIntrinsicWidth() * f[Matrix.MSCALE_X]); 
    imageScaledHeight = Math.round(getBackground().getIntrinsicHeight() * f[Matrix.MSCALE_Y]); 

    return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false; 
} 

मैं काम कोड बनाने के लिए एक छोटे से परिवर्तन किया है कि: getBackground() getDrawable

के बजाय

संपादित करें 2: ठीक है Ive गया यह, मैं इस में क्या कर रहा था गलत रास्ता। आप कोड अच्छे हैं। छवि को सेट करने के लिए मैं view.seBackground() ... view.setImageDrawable() के बजाय उपयोग कर रहा था। अब सब कुछ काम करता है। हो सकता है कि मैं केवल जाँच करेगा कि क्या यह एक बड़े क्षेत्र है कि आयत की स्केलिंग आग बनाने के लिए संभव है

+0

हाय @ वहन 84! क्षमा करें, मैंने आपको कोड से उलझन में डाल दिया। आपने अपनी समस्या को कैसे ठीक किया? मैं धागे में खो गया। इसके अलावा @TheHippo धन्यवाद सुझाव। मुझे लगता है कि उसका जवाब छवि को सेट करने का सबसे अच्छा तरीका है। –

+1

क्या कोई भी इसे अंतिम कोड और ऊपर संपादित करने के तरीके को संपादित कर सकता है ?? – Hasham

+0

हाय! कोड हिप्पो द्वारा पोस्ट किया गया काम करता है! मैं इसे गलत तरीके से कर रहा था! – Vahn84

0

मैं एक लाइब्रेरी मिली जो इसका समर्थन करती है: https://android-arsenal.com/details/1/2366 से SimpleCropView। आम तौर पर, मैं इसकी अनुशंसा नहीं करता, इसका प्रदर्शन मूल एंड्रॉइड क्रॉपिंग ऐप्स से बहुत दूर है।

मैं इसे उपयोग करने की कोशिश की है, और मेरे विचार कर रहे हैं:

  • सच में अपने ऐप्लिकेशन में लागू करने के लिए सरल, मेरे बारे में 5 मिनट के फसल और रोटेशन कार्यक्षमता अपने मौजूदा अनुप्रयोग के साथ काम कर पाने के ले लिया

  • फसल क्षेत्र का पुन: आकार दर्दनाक रूप से धीमा है, मैं अपने उपयोगकर्ता को यह देखना नहीं चाहूंगा।

अद्यतन: वास्तव में, मैं पाया है Github पर jdamcd/android-फसल के रूप में एक बहुत अच्छा समाधान: https://github.com/jdamcd/android-crop सारांश:

  • बहुत ही सरल अपने अनुप्रयोग में उपयोग करने के लिए

  • फास्ट, चूंकि यह देशी गैलरी ऐप से कोड का उपयोग करता है

  • अनुकूलन योग्य, यदि आप चाहते हैं इसके साथ खेलने में कुछ समय बिताएं। डिफ़ॉल्ट रूप से, यह आपको एक गतिविधि प्रदान करता है जहां आप फसल करते हैं। यदि आप इसे अपनी गतिविधि में एकीकृत करना चाहते हैं, तो थोड़ा सा समय लगेगा। (मेरी परियोजना के लिए मुझे इसे एकीकृत करना अच्छा लगेगा, और भविष्य में ऐसा करेगा, लेकिन अब के लिए एक अलग गतिविधि पर्याप्त है)।

उम्मीद है कि यह कुछ अंतर्दृष्टि प्रदान करता है!

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