2012-10-31 21 views
9

मैं कैमरे के माध्यम से कैप्चर करने वाले बिटमैप पर एक परिप्रेक्ष्य परिवर्तन करने की कोशिश कर रहा हूं। उपयोगकर्ता एक आयताकार वस्तु के चारों ओर एक बाउंडिंग क्वाड (जैसा कि सफेद बॉक्स द्वारा चित्रित किया गया है) समायोजित करता है। मैं तो नीचे दिए गए कोड का उपयोग कर एक आयताकार छवि को यह बदलने के लिए प्रयास:एंड्रॉइड पर छवि का एक परिप्रेक्ष्य परिवर्तन फसल

public static Bitmap perspectiveTransformation(Bitmap bitmap,BoundingQuad boundingQuad) 
{ 
    Matrix matrix = new Matrix(); 
    float[] dst = new float[] { 
      0, 
      0, 
      bitmap.getWidth(), 
      0, 
      bitmap.getWidth(), 
      bitmap.getHeight(), 
      0, 
      bitmap.getHeight() 
    }; 
    float[] src = new float[] { 
      boundingQuad.topLeft.x, 
      boundingQuad.topLeft.y, 
      boundingQuad.topRight.x, 
      boundingQuad.topRight.y, 
      boundingQuad.bottomRight.x, 
      boundingQuad.bottomRight.y, 
      boundingQuad.bottomLeft.x, 
      boundingQuad.bottomLeft.y 
    }; 
    matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); 
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
} 

हालांकि मेरी जिसके परिणामस्वरूप छवि छवि डेटा मेरी ट्रैक्टर की सीमा के बाहर है कि होता है। यह स्वीकार्य होगा अगर मैं समझ सकता हूं कि ट्रैक्टर के निर्देशांक परिवर्तन के बाद क्या हैं, इसलिए मैं परिणाम फसल कर सकता हूं लेकिन मुझे बिल्कुल नहीं पता कि यह कैसे करना है।

परिवर्तन के बाद ट्रैक्टर के निर्देशांक ढूंढने या आदर्श रूप से इस स्थिति को रोकने के लिए एक रास्ता खोजने में किसी भी मदद की सराहना की जाएगी।

इनपुट:

http://i.stack.imgur.com/33RfN.png

आउटपुट:

http://i.stack.imgur.com/zWFvA.png

+0

आप एक समाधान मिला? मेरे साथ भी वही दिक्कत है। –

+0

@ रोमैन-लड़का शायद आपको उस समस्या का संकेत हो सकता है? –

उत्तर

-2

आप अपने नए Bitmap छवि बनाने के बाद, आप कॉल कर सकते हैं Android के लिए एक 'फसल की मंशा का निर्माण करके फसल कार्यक्षमता में बनाया गया और इसे कॉल करना, उदाहरण:

Intent cropIntent = new Intent("com.android.camera.action.CROP"); 

// Put in 'Extras' here to build the intent 

// Start the activity. It will be handled by returning data to onActivityResult 
startActivityForResult(cropIntent, PIC_CROP); // PIC_CROP is just an arbitrary tag name. 

एंड्रॉइड में छवि क्रॉपिंग के बारे में अधिक जानकारी here से प्राप्त की जा सकती है।

आप भी इस काम करने के लिए आपके ऐप की मेनिफेस्ट फ़ाइल में निम्न जोड़ने की आवश्यकता होगी:

<uses-feature android:name="android.hardware.camera" ></uses-feature> 
<uses-permission android:name="android.permission.CAMERA" /> 
3

मैं एक ही समस्या थी और परिवर्तन के बाद आयत के निर्देशांक खोजकर इसे हल किया।

इन निर्देशांकों को ढूंढने के लिए आपको समझना होगा कि क्या हो रहा है। मैट्रिक्स एक परिप्रेक्ष्य परिवर्तन को परिभाषित करता है, जो क्वाड के 4 किनारे-बिंदुओं और संबंधित बिंदुओं द्वारा दिया जाता है। आप नीचे दिए गए कोड के साथ यह किया है:

Matrix matrix = new Matrix(); 
float[] dst = new float[] { 
     0, 
     0, 
     bitmap.getWidth(), 
     0, 
     bitmap.getWidth(), 
     bitmap.getHeight(), 
     0, 
     bitmap.getHeight() 
}; 
float[] src = new float[] { 
     boundingQuad.topLeft.x, 
     boundingQuad.topLeft.y, 
     boundingQuad.topRight.x, 
     boundingQuad.topRight.y, 
     boundingQuad.bottomRight.x, 
     boundingQuad.bottomRight.y, 
     boundingQuad.bottomLeft.x, 
     boundingQuad.bottomLeft.y 
}; 
matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); 

इस का अर्थ है (उदाहरण के लिए) है कि अपने ट्रैक्टर के ऊपरी-बाएं बिंदु बिंदु (0,0) के लिए बदल जाता है। आप बिंदुओं पर मैट्रिक्स लागू करके और परिणामी मानों की जांच करके इसे सत्यापित कर सकते हैं। मैट्रिक्स को लागू करने के लिए आप विधि mapPoints(...) का उपयोग कर सकते हैं। परिभाषित परिवर्तन-मैट्रिक्स ठीक काम करता है। बिटमैप के निर्माण से इस बदलाव परिणामों की (फर्स्ट लुक पर) अजीब व्यवहार:

return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 

जिसके परिणामस्वरूप बिटमैप, गलत हो रहा है, क्योंकि कुछ अंक (शीर्ष के बाईं ओर उदाहरण के लिए सभी बिंदुओं ट्रैक्टर का बायां बिंदु) नकारात्मक निर्देशांक में परिवर्तित हो जाते हैं और यदि आप बिटमैप में कुछ आकर्षित करना चाहते हैं तो निर्देशांक सकारात्मक होना चाहिए। इस वजह से रूपांतरित बिंदु शिफ्ट होते हैं और इससे बिटमैप में परिवर्तित बिंदुओं के अजीब निर्देशांक होते हैं।

निष्कर्ष निकालने के लिए: अंक नए निर्देशांक में सही ढंग से परिवर्तित हो जाते हैं, लेकिन प्रदर्शित नहीं किए जा सकते हैं और इसके कारण उन्हें स्थानांतरित किया जाता है और बिटमैप में परिवर्तित बिंदुओं के स्थानांतरित निर्देशांक निर्देशांक नहीं होते हैं, जिन्हें परिभाषित किया जाता है परिवर्तन-मैट्रिक्स।

इस समस्या को हल करने और बिटमैप में परिवर्तित बिंदुओं के उचित निर्देशांक प्राप्त करने के लिए, आपको शिफ्ट के मानों की गणना करना होगा। शिफ्ट में एक्स-वैल्यू और वाई-वैल्यू होता है।

एक्स-वैल्यू की गणना करने के लिए मैंने शीर्ष-बाएं बिंदु के एक्स-वैल्यू को बदल दिया और मूल छवि के निचले-बाएं बिंदु के एक्स-वैल्यू को पहले परिभाषित मैट्रिक्स के साथ बदल दिया। या तो शीर्ष-बाएं बिंदु या निचले बाएं बिंदु को परिणामी बिटमैप की बायीं सीमा में बदल दिया गया है और इसके कारण इस बिंदु के बिटमैप-समन्वय का x-value 0 के बराबर है और अस्वीकृत (क्योंकि x- मूल्य सकारात्मक होना चाहिए) रूपांतरित समन्वय का एक्स-मान शिफ्ट का एक्स-मान है। बिंदु, जो परिणामी बिटमैप की बायीं सीमा में परिवर्तित हो जाता है वह अधिकतम नकारात्मक x-value के साथ बिंदु है। इसलिए शिफ्ट का एक्स-वैल्यू ट्रांसफॉर्म किए गए टॉप-बाएं और निचले बाएं बिंदु के अस्वीकृत एक्स-मानों का अधिकतम है।

वाई-वैल्यू की गणना करने के लिए मैंने शीर्ष-बाएं बिंदु के वाई-मान और मूल छवि के शीर्ष-दाएं बिंदु के वाई-मान को बदल दिया, क्योंकि यह संभावित बिंदु हैं जो शीर्ष पर परिवर्तित हो गए हैं परिणामी बिटमैप की सीमा और रूपांतरित बिंदु के वाई-मान परिणामी बिटमैप में 0 के बराबर है। रूपांतरित वाई-मानों के अधिकतम अस्वीकृत मूल्यों को फिर से ले कर, आपको शिफ्ट का वाई-मान मिलता है।

जिसके परिणामस्वरूप कोड इस तरह दिखता है:

float[] mappedTL = new float[] { 0, 0 }; 
    matrix.mapPoints(mappedTL); 
    int maptlx = Math.round(mappedTL[0]); 
    int maptly = Math.round(mappedTL[1]); 

    float[] mappedTR = new float[] { bitmap.getWidth(), 0 }; 
    matrix.mapPoints(mappedTR); 
    int maptrx = Math.round(mappedTR[0]); 
    int maptry = Math.round(mappedTR[1]); 

    float[] mappedLL = new float[] { 0, bitmap.getHeight() }; 
    matrix.mapPoints(mappedLL); 
    int mapllx = Math.round(mappedLL[0]); 
    int maplly = Math.round(mappedLL[1]); 

    int shiftX = Math.max(-maptlx, -mapllx); 
    int shiftY = Math.max(-maptry, -maptly); 

    Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
    return Bitmap.createBitmap(resultBitmap, shiftX, shiftY, bitmap.getWidth(), bitmap.getHeight(), null, true);