2013-02-27 5 views
11

को बदलने के बिना मैं निम्नलिखित समस्या का समाधान ढूंढ रहा हूं: Bitmap के आकार को एक निश्चित आकार में कैसे बदलें (उदाहरण के लिए 512x128)। बिटमैप सामग्री का पहलू अनुपात संरक्षित किया जाना चाहिए।एक निश्चित मान पर बिटमैप का आकार बदलना, लेकिन पहलू अनुपात

मुझे लगता है कि यह कुछ इस तरह होना चाहिए:

  • पैमाने मूल बिटमैप नीचे पहलू अनुपात

  • रखने के साथ 512x128 पिक्सल फिट करने के लिए एक खाली 512x128 बिटमैप बनाने रिक्त बिटमैप (केंद्रित) में स्केल किए गए प्रतिलिपि

इसे प्राप्त करने का सबसे आसान तरीका क्या है?

यह सब कारण है कि GridView एक छवि के पहलू अनुपात दूसरे से अलग होने पर लेआउट को गड़बड़ कर देता है। यहाँ एक स्क्रीनशॉट है (: 1 पिछले एक को छोड़कर सभी छवियों को 4 के पहलू अनुपात):

screenshot

उत्तर

25

इसे आज़माएं, अनुपात की गणना करें और फिर पुनर्विक्रय करें।

private Bitmap scaleBitmap(Bitmap bm) { 
    int width = bm.getWidth(); 
    int height = bm.getHeight(); 

    Log.v("Pictures", "Width and height are " + width + "--" + height); 

    if (width > height) { 
     // landscape 
     float ratio = (float) width/maxWidth; 
     width = maxWidth; 
     height = (int)(height/ratio); 
    } else if (height > width) { 
     // portrait 
     float ratio = (float) height/maxHeight; 
     height = maxHeight; 
     width = (int)(width/ratio); 
    } else { 
     // square 
     height = maxHeight; 
     width = maxWidth; 
    } 

    Log.v("Pictures", "after scaling Width and height are " + width + "--" + height); 

    bm = Bitmap.createScaledBitmap(bm, width, height, true); 
    return bm; 
} 
+2

प्लस एक सरल समाधान के लिए जोड़ा गया। लेकिन मैं int अनुपात को फ्लोट/डबल अनुपात में बदल दूंगा क्योंकि int/int अपवाद उत्पन्न कर सकता है जब यह 0 से विभाजित करने का प्रयास करता है। –

+0

बहुत बढ़िया सरल समाधान! इंक की बजाय फ्लोट्स का उपयोग करना जरूरी है। नतीजा ज्यादातर समय गलत हो सकता है (उदाहरण के लिए, जब यह 1.4 होना चाहिए तो अनुपात 1 हो जाता है)। – xip

+0

@ हिकारू आप सही हैं, ऐसा करना चाहते थे लेकिन कभी नहीं मिला। संपादन और अनुस्मारक के लिए धन्यवाद -) –

0

https://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)

और सुनिश्चित करें कि दोनों dstWidth और dstHeightsrc.getWidth()*scale और src.getHeight()*scale से प्राप्त कर रहे हैं , जहां scale एक मान है जिसे आपको यह सुनिश्चित करने के लिए निर्धारित करना है कि स्केल किए गए बिटमैप 512x128 के अंदर फिट बैठता है।

+0

'createScaledBitmap' मेरी समस्या का समाधान नहीं करता: यहाँ एक जवाब है कि करता है। यही वह है जो मैं पहले से ही उपयोग करता हूं। उदाहरण में आखिरी छवि को इस तरह से बढ़ा दिया गया है। –

+0

यदि आपके पास पहले से ही बिटमैप (512 से कम चौड़ाई या 128 से कम ऊंचाई आपके उदाहरण में) है, तो बस इन विशेषताओं को अपने ग्रिड व्यू आइटम के ImageView में एंड्रॉइड पर सेट करें: layout_width = "512dp" और एंड्रॉइड: layout_height = "128dp "और एंड्रॉइड: स्केल टाइप =" सेंटर "या एंड्रॉइड: स्केल टाइप =" सेंटर इनसाइड " –

+0

मेरी व्याख्या के अनुसार उदाहरण में आखिरी छवि पहले ही स्केल हो चुकी है, इसलिए यह पहले से ही अधिकतम है। 128 पीएक्स उच्च। इसके बावजूद, छवि दृश्य अन्य छवियों की तुलना में इसे बड़ा दिखाता है। इसके अलावा मैं 512x128dp ग्रिड के साथ एक छवि दृश्य नहीं चाहता हूं। –

2

मैंने अपनी परियोजनाओं में कई बार एक ही समस्या पर ठोकर खाई है और हर बार समय (और आलस्य) की कमी के कारण मैं इष्टतम समाधान से कम संतुष्ट हूं। लेकिन हाल ही में मुझे इस विशेष मुद्दे को तोड़ने के लिए कुछ समय मिला। यहां मेरा समाधान है और मुझे उम्मीद है कि यह किसी को लाइन के नीचे मदद करता है ...

Bitmap scaleDownLargeImageWithAspectRatio(Bitmap image) 
      { 
       int imaheVerticalAspectRatio,imageHorizontalAspectRatio; 
       float bestFitScalingFactor=0; 
       float percesionValue=(float) 0.2; 

       //getAspect Ratio of Image 
       int imageHeight=(int) (Math.ceil((double) image.getHeight()/100)*100); 
       int imageWidth=(int) (Math.ceil((double) image.getWidth()/100)*100); 
       int GCD=BigInteger.valueOf(imageHeight).gcd(BigInteger.valueOf(imageWidth)).intValue(); 
       imaheVerticalAspectRatio=imageHeight/GCD; 
       imageHorizontalAspectRatio=imageWidth/GCD; 
       Log.i("scaleDownLargeImageWIthAspectRatio","Image Dimensions(W:H): "+imageWidth+":"+imageHeight); 
       Log.i("scaleDownLargeImageWIthAspectRatio","Image AspectRatio(W:H): "+imageHorizontalAspectRatio+":"+imaheVerticalAspectRatio); 

       //getContainer Dimensions 
       int displayWidth = getWindowManager().getDefaultDisplay().getWidth(); 
       int displayHeight = getWindowManager().getDefaultDisplay().getHeight(); 
       //I wanted to show the image to fit the entire device, as a best case. So my ccontainer dimensions were displayWidth & displayHeight. For your case, you will need to fetch container dimensions at run time or you can pass static values to these two parameters 

       int leftMargin = 0; 
       int rightMargin = 0; 
       int topMargin = 0; 
       int bottomMargin = 0; 
       int containerWidth = displayWidth - (leftMargin + rightMargin); 
       int containerHeight = displayHeight - (topMargin + bottomMargin); 
       Log.i("scaleDownLargeImageWIthAspectRatio","Container dimensions(W:H): "+containerWidth+":"+containerHeight); 

       //iterate to get bestFitScaleFactor per constraints 
       while((imageHorizontalAspectRatio*bestFitScalingFactor <= containerWidth) && 
         (imaheVerticalAspectRatio*bestFitScalingFactor<= containerHeight)) 
       { 
        bestFitScalingFactor+=percesionValue; 
       } 

       //return bestFit bitmap 
       int bestFitHeight=(int) (imaheVerticalAspectRatio*bestFitScalingFactor); 
       int bestFitWidth=(int) (imageHorizontalAspectRatio*bestFitScalingFactor); 
       Log.i("scaleDownLargeImageWIthAspectRatio","bestFitScalingFactor: "+bestFitScalingFactor); 
       Log.i("scaleDownLargeImageWIthAspectRatio","bestFitOutPutDimesions(W:H): "+bestFitWidth+":"+bestFitHeight); 
       image=Bitmap.createScaledBitmap(image, bestFitWidth,bestFitHeight, true); 

       //Position the bitmap centre of the container 
       int leftPadding=(containerWidth-image.getWidth())/2; 
       int topPadding=(containerHeight-image.getHeight())/2; 
       Bitmap backDrop=Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.RGB_565); 
       Canvas can = new Canvas(backDrop); 
       can.drawBitmap(image, leftPadding, topPadding, null); 

       return backDrop; 
      } 
18

कोन डेमन का उत्तर हमेशा अधिकतम ऊंचाई और अधिकतम चौड़ाई का सम्मान नहीं करता है।

private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) { 
    if (maxHeight > 0 && maxWidth > 0) { 
     int width = image.getWidth(); 
     int height = image.getHeight(); 
     float ratioBitmap = (float) width/(float) height; 
     float ratioMax = (float) maxWidth/(float) maxHeight; 

     int finalWidth = maxWidth; 
     int finalHeight = maxHeight; 
     if (ratioMax > 1) { 
      finalWidth = (int) ((float)maxHeight * ratioBitmap); 
     } else { 
      finalHeight = (int) ((float)maxWidth/ratioBitmap); 
     } 
     image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true); 
     return image; 
    } else { 
     return image; 
    } 
} 
+0

मेरा जवाब चुरा रहा है तो ठीक है। बेशक maxWidth और maxHeight विधि पैरा के बजाय कक्षा चर हैं। –

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