2009-09-10 17 views
7

करने के लिए नीचे एक UIImage पैमाने पर करने को देखते हुए एक UIImage किसी भी आयाम की, मैं एक वर्ग "आइकन" आकार के संस्करण, एक तरफ करने के लिए px पिक्सल उत्पन्न करने के लिए चाहते हैं किसी भी विकृति (खींच) के बिना। हालांकि, मैं थोड़ा सा झुकाव में भाग रहा हूँ। बिल्कुल यकीन नहीं है कि समस्या कहां है। यहां मैं अभी तक क्या कर रहा हूं।UIRectClip का उचित उपयोग आइकन आकार

, सबसे पहले एक UImagesize को देखते हुए, मैं तीन बातें निर्धारित: जब नीचे छवि स्केलिंग ratio उपयोग करने के लिए; एक delta, और एक offset (हमारे वांछित आइकन आकार और लंबाई की ओर के बीच अंतर) (जो यह पता लगाने के लिए किया जाता हमारे मूल समन्वय जब छवि कतरन):

if (size.width > size.height) { 
    ratio = px/size.width; 
    delta = (ratio*size.width - ratio*size.height); 
    offset = CGPointMake(delta/2, 0); 
} else { 
    ratio = px/size.height; 
    delta = (ratio*size.height - ratio*size.width); 
    offset = CGPointMake(0, delta/2); 
} 

अब मान लें कि आप एक छवि है चलो 480px उच्च द्वारा 640px चौड़ा, और हम इसमें से 50px x 50px आइकन प्राप्त करना चाहते हैं। चौड़ाई ऊंचाई से अधिक है, तो हमारी गणना कर रहे हैं:

ratio = 50px/640px = 0.078125 
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px 
offset = {x=6.25, y=0} 

इसके बाद, मैं बनाने के एक CGRectrect कि इतना बड़ा विरूपण के बिना हमारे वांछित आइकन आकार, प्लस कतरन के लिए एक clipRect करने के लिए नीचे कट जाने की है प्रयोजनों:

CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta, 
            (ratio * size.height) + delta); 
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px); 

ऊपर से हमारे मूल्यों को प्रतिस्थापित करने पर, हम पाते हैं:

rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0} 
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0} 

तो अब हमारे पास काम करने के लिए 50 पीएक्स उच्च आयत द्वारा 62.5 पीएक्स चौड़ा है, और एक क्लिपिंग आयताकार जो "मध्य" 50x50 भाग को पकड़ता है।

घर के खिंचाव पर! इसके बाद, हमने अपना चित्र संदर्भ स्थापित किया है, UIImage (जिसे myImage यहां कहा जाता है) को रेक्ट में सेट करें, क्लिपिंग आयत सेट करें, इसे (संभवतः अब-क्लिप) छवि प्राप्त करें, इसका उपयोग करें, और अंततः हमारे छवि संदर्भ को साफ़ करें:

UIGraphicsBeginImageContext(rect.size); 
[myImage drawInRect:rect]; 
UIRectClip(clipRect); 
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext(); 

// Do something with the icon here ... 

UIGraphicsEndImageContext(); 

केवल एक समस्या: क्लिपिंग कभी नहीं होती! मैं एक छवि 63px चौड़ा x 50px उच्च के साथ समाप्त होता है। :(

शायद मैं UIRectClip का दुरुपयोग/गलतफहमी कर रहा हूं? मैंने विभिन्न चीजों को चारों ओर घूमने की कोशिश की है: rect और clipRect के उपयोग को स्वैप करना, ड्राइन्रैक्ट से पहले। कोई पाँसा नहीं।

मैंने इस विधि के उदाहरण के लिए ऑनलाइन खोज करने की कोशिश की, इसका कोई फायदा नहीं हुआ।

द्वारा वर्तमान कतरन पथ निर्दिष्ट आयत के साथ अन्तर्विभाजक संशोधित करता है: रिकॉर्ड के लिए, UIRectClip के रूप में परिभाषित किया गया है।

फेरबदल बातें हमें हो जाता है एक छोटा सा करीब चारों ओर:

UIGraphicsBeginImageContext(clipRect.size); 
UIRectClip(rect); 
[myImage drawInRect:rect]; 

अब हम विरूपण की जरूरत नहीं है, लेकिन काटा छवि मूल पर केंद्रित नहीं है के रूप में मैं उम्मीद थी।फिर भी, कम से कम छवि 50x50 है, हालांकि परिवर्तनीय नाम अब शफल होने के परिणामस्वरूप फूले हुए हैं। (मैं सम्मानपूर्वक पाठक के लिए अभ्यास के रूप में नामांकन छोड़ दूंगा।)

उत्तर

7

यूरेका! मेरे पास चीजें थोड़ी-थोड़ी मिश्रित थीं। यह काम करता है:

CGRect clipRect = CGRectMake(-offset.x, -offset.y, 
          (ratio * size.width) + delta, 
          (ratio * size.height) + delta); 
UIGraphicsBeginImageContext(CGSizeMake(px, px)); 
UIRectClip(clipRect); 
[myImage drawInRect:clipRect]; 
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext(); 

// Do something with the icon here ... 

UIGraphicsEndImageContext(); 

rect के लिए और आवश्यकता नहीं है। यह क्लिप क्लिपिंग आयताकार में नकारात्मक ऑफ़सेट का उपयोग कर प्रतीत होता है, जिससे हम अपनी 50 x 50 छवि (इस उदाहरण में) को पकड़ना चाहते हैं।

शायद एक आसान तरीका है। यदि हां, तो कृपया वजन लें!

1

मैं एक समान चीज़ प्राप्त करना चाहता था लेकिन मूल पोस्टर से जवाब काफी काम नहीं किया। यह छवि विकृत कर दिया। यह अच्छी तरह से पूरी तरह से क्योंकि वह पूरे समाधान पोस्ट नहीं हो सकता है और कैसे चर initialised कर रहे हैं में से कुछ बदल गया था:

(if (size.width > size.height) 
     ratio = px/size.width; 

मेरी समाधान (जो स्रोत छवि से सबसे बड़ी संभव वर्ग उपयोग करना चाहता था के लिए गलत था)। इसके अलावा UIClipRect का उपयोग करना आवश्यक नहीं है - यदि आप संदर्भ को उस छवि का आकार बनाते हैं जिसे आप निकालना चाहते हैं, वैसे भी उस वास्तविकता के बाहर कोई वास्तविक चित्र नहीं किया जाएगा। यह सिर्फ छवि संदर्भ के आकार को स्केल करने और मूल निर्देशांक में से एक को ऑफ़सेट करने का विषय है। मैं नीचे मेरी समाधान पोस्ट किया है:

+(UIImage *)makeIconImage:(UIImage *)image 
{ 
    CGFloat destSize = 400.0; 
    CGRect rect = CGRectMake(0, 0, destSize, destSize); 

    UIGraphicsBeginImageContext(rect.size); 

    if(image.size.width != image.size.height) 
    { 
     CGFloat ratio; 
     CGRect destRect; 

     if (image.size.width > image.size.height) 
     { 
      ratio = destSize/image.size.height; 

      CGFloat destWidth = image.size.width * ratio; 
      CGFloat destX = (destWidth - destSize)/2.0; 

      destRect = CGRectMake(-destX, 0, destWidth, destSize); 

     } 
     else 
     { 
      ratio = destSize/image.size.width; 

      CGFloat destHeight = image.size.height * ratio; 
      CGFloat destY = (destHeight - destSize)/2.0; 

      destRect = CGRectMake(0, destY, destSize, destHeight); 
     } 
     [image drawInRect:destRect]; 
    } 
    else 
    { 
     [image drawInRect:rect]; 
    } 
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    return scaledImage; 
} 
+0

इस साझा करने के लिए धन्यवाद! यह थोड़ी देर हो गया है क्योंकि मैंने देखा है कि मैंने क्या समाप्त किया था। मैं निश्चित रूप से अपनी विधि का उपयोग कर किसी विकृति के लिए नहीं चाहता था या इरादा नहीं चाहता था। आपका "सबसे बड़ा संभव वर्ग" समझदार लगता है, और मैं यूआईआरईटीक्लिप को जरूरी नहीं सुन रहा हूं। (अन्य पाठक, कृपया वजन लें और देखें कि यह आपके लिए कैसे उड़ता है!) –

+0

धन्यवाद, विशेष रूप से वाक्य के लिए "यूआईसीएलआईपीआरईटी का उपयोग करना भी जरूरी नहीं है - यदि आप संदर्भ को उस छवि का आकार बनाते हैं जिसे आप निकालना चाहते हैं, वैसे भी उस रेक्ट के बाहर कोई वास्तविक चित्र नहीं किया जाएगा " – xaphod

0

wheeliebin उत्तर सही है, लेकिन वह destY

के सामने एक ऋण चिह्न भूल
destRect = CGRectMake(0, -destY, destSize, destHeight); 
संबंधित मुद्दे