दिलचस्प पोस्ट
स्काला में, "प्रारंभिक प्रारंभकर्ता" क्या है? स्कैनर बनाम स्ट्रिंगटोकनाइज़र बनाम स्ट्रिंग। स्प्लिट पायथन के उपयोग से एक सीक्लिटे 3 डेटाबेस तालिका में सीएसवी फ़ाइल आयात करना एंड्रॉइड में निजी एपीआई कुंजी को स्टोर करने के लिए सर्वश्रेष्ठ अभ्यास बिना नई लाइन या अंतरिक्ष कैसे मुद्रित करें? कैसे PowerShell के साथ एक ज़िप संग्रह बनाने के लिए? MySQL, नल या रिक्त स्ट्रिंग को सम्मिलित करना बेहतर है? फ्लेक्स कंटेनर में समान ऊंची पंक्तियां बाहरी लाइब्रेरी से सीमके लिंक टंक्रीट में विभिन्न अनुप्रयोगों के बीच सत्र का हिस्सा साझा करने का कोई भी तरीका? Google OAuth ताज़ा करें टोकन प्राप्त नहीं कर रहा है उच्च आयामी डेटा में निकटतम पड़ोसियों? एक्सेल फाइलों के माध्यम से लूप कैसे करें और उन्हें एसएसआईएस पैकेज का उपयोग करके डेटाबेस में लोड करें? Google Drive Android API में DriveId.getResourceId () का अप्रत्याशित परिणाम क्लिक ईवेंट श्रोता के लिए 'वापसी झूठी' जोड़ने का क्या असर है?

UIImage: आकार बदलें, फिर फसल

मैं इस चेहरे को शाब्दिक दिनों के लिए आज भी अपने चेहरे पर डाल रहा हूं और फिर भी मैं लगातार महसूस करता हूं कि मैं रहस्योद्घाटन के किनारे पर हूं, मैं अपने लक्ष्य को हासिल नहीं कर सकता

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

कैमरा या लाइब्रेरी से मूल छवि प्राप्त करना, तुच्छ था मुझे इस बात पर हैरान है कि अन्य दो चरणों में कितना मुश्किल साबित हुआ है।

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

वेब के समाधान से एकत्रित समाधान "UIImage: आकार बदलें, फिर फसल"

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

@implementation UIImage (Extras) #pragma mark - #pragma mark Scale and crop image - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize { UIImage *sourceImage = self; UIImage *newImage = nil; CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if (widthFactor > heightFactor) { scaleFactor = widthFactor; // scale to fit height } else { scaleFactor = heightFactor; // scale to fit width } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor > heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; } else { if (widthFactor < heightFactor) { thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } } UIGraphicsBeginImageContext(targetSize); // this will crop CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); if(newImage == nil) { NSLog(@"could not scale image"); } //pop the context to get back to the default UIGraphicsEndImageContext(); return newImage; } 

एक पुराने पोस्ट में आपके UIImage का आकार बदलने के लिए एक विधि है। संबंधित भाग इस प्रकार है:

 + (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize; { UIGraphicsBeginImageContext( newSize ); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

जहां तक ​​फसल होती है, मेरा मानना ​​है कि यदि आप संदर्भ के लिए स्केलिंग के लिए एक अलग आकार का उपयोग करने के लिए विधि को बदलते हैं, तो आपकी परिणामी छवि को संदर्भ की सीमा तक काटा जाना चाहिए।

 + (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)targetSize { //If scaleFactor is not touched, no scaling will occur CGFloat scaleFactor = 1.0; //Deciding which factor to use to scale the image (factor = targetSize / imageSize) if (image.size.width > targetSize.width || image.size.height > targetSize.height) if (!((scaleFactor = (targetSize.width / image.size.width)) > (targetSize.height / image.size.height))) //scale to fit width, or scaleFactor = targetSize.height / image.size.height; // scale to fit heigth. UIGraphicsBeginImageContext(targetSize); //Creating the rect where the scaled image is drawn in CGRect rect = CGRectMake((targetSize.width - image.size.width * scaleFactor) / 2, (targetSize.height - image.size.height * scaleFactor) / 2, image.size.width * scaleFactor, image.size.height * scaleFactor); //Draw the image into the rect [image drawInRect:rect]; //Saving the image, ending image context UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } 

मैं यह प्रस्ताव करता हूं क्या वह एक सौंदर्य नहीं है? 😉

छवियों के रीसाइज से संबंधित कोड का एक बड़ा टुकड़ा है + कई अन्य ऑपरेशन छवियों का आकार बदलने का तरीका समझने की कोशिश करते समय मैं इस एक ओर आया था … http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

हेयर यू गो। यह एक सही है 😉

संपादित करें: नीचे टिप्पणी देखें – "कुछ चित्रों के साथ काम नहीं करता, इसके साथ विफल रहता है: CGContextSetInterpolationQuality: अमान्य संदर्भ 0x0 त्रुटि"

 // Resizes the image according to the given content mode, taking into account the image's orientation - (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode imageToScale:(UIImage*)imageToScale bounds:(CGSize)bounds interpolationQuality:(CGInterpolationQuality)quality { //Get the size we want to scale it to CGFloat horizontalRatio = bounds.width / imageToScale.size.width; CGFloat verticalRatio = bounds.height / imageToScale.size.height; CGFloat ratio; switch (contentMode) { case UIViewContentModeScaleAspectFill: ratio = MAX(horizontalRatio, verticalRatio); break; case UIViewContentModeScaleAspectFit: ratio = MIN(horizontalRatio, verticalRatio); break; default: [NSException raise:NSInvalidArgumentException format:@"Unsupported content mode: %d", contentMode]; } //...and here it is CGSize newSize = CGSizeMake(imageToScale.size.width * ratio, imageToScale.size.height * ratio); //start scaling it CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height)); CGImageRef imageRef = imageToScale.CGImage; CGContextRef bitmap = CGBitmapContextCreate(NULL, newRect.size.width, newRect.size.height, CGImageGetBitsPerComponent(imageRef), 0, CGImageGetColorSpace(imageRef), CGImageGetBitmapInfo(imageRef)); CGContextSetInterpolationQuality(bitmap, quality); // Draw into the context; this scales the image CGContextDrawImage(bitmap, newRect, imageRef); // Get the resized image from the context and a UIImage CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap); UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; // Clean up CGContextRelease(bitmap); CGImageRelease(newImageRef); return newImage; } 

यह स्विफ्ट में जेन सेलल्स के उत्तर का एक संस्करण है चीयर्स!

 public func resizeImage(image: UIImage, size: CGSize) -> UIImage? { var returnImage: UIImage? var scaleFactor: CGFloat = 1.0 var scaledWidth = size.width var scaledHeight = size.height var thumbnailPoint = CGPointMake(0, 0) if !CGSizeEqualToSize(image.size, size) { let widthFactor = size.width / image.size.width let heightFactor = size.height / image.size.height if widthFactor > heightFactor { scaleFactor = widthFactor } else { scaleFactor = heightFactor } scaledWidth = image.size.width * scaleFactor scaledHeight = image.size.height * scaleFactor if widthFactor > heightFactor { thumbnailPoint.y = (size.height - scaledHeight) * 0.5 } else if widthFactor < heightFactor { thumbnailPoint.x = (size.width - scaledWidth) * 0.5 } } UIGraphicsBeginImageContextWithOptions(size, true, 0) var thumbnailRect = CGRectZero thumbnailRect.origin = thumbnailPoint thumbnailRect.size.width = scaledWidth thumbnailRect.size.height = scaledHeight image.drawInRect(thumbnailRect) returnImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return returnImage } 

मैंने ब्रैड लार्सन के कोड को संशोधित किया इसे दिए गए रीक्स्ट में छवि को भरना होगा।

 -(UIImage*) scaleAndCropToSize:(CGSize)newSize; { float ratio = self.size.width / self.size.height; UIGraphicsBeginImageContext(newSize); if (ratio > 1) { CGFloat newWidth = ratio * newSize.width; CGFloat newHeight = newSize.height; CGFloat leftMargin = (newWidth - newHeight) / 2; [self drawInRect:CGRectMake(-leftMargin, 0, newWidth, newHeight)]; } else { CGFloat newWidth = newSize.width; CGFloat newHeight = newSize.height / ratio; CGFloat topMargin = (newHeight - newWidth) / 2; [self drawInRect:CGRectMake(0, -topMargin, newSize.width, newSize.height/ratio)]; } UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

स्वीकार करने के लिए Xamarin.iOS संस्करण का आकार बदलने और फिर फसल UIImage (पहलू भरण) कैसे नीचे है

  public static UIImage ScaleAndCropImage(UIImage sourceImage, SizeF targetSize) { var imageSize = sourceImage.Size; UIImage newImage = null; var width = imageSize.Width; var height = imageSize.Height; var targetWidth = targetSize.Width; var targetHeight = targetSize.Height; var scaleFactor = 0.0f; var scaledWidth = targetWidth; var scaledHeight = targetHeight; var thumbnailPoint = PointF.Empty; if (imageSize != targetSize) { var widthFactor = targetWidth / width; var heightFactor = targetHeight / height; if (widthFactor > heightFactor) { scaleFactor = widthFactor;// scale to fit height } else { scaleFactor = heightFactor;// scale to fit width } scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor > heightFactor) { thumbnailPoint.Y = (targetHeight - scaledHeight) * 0.5f; } else { if (widthFactor < heightFactor) { thumbnailPoint.X = (targetWidth - scaledWidth) * 0.5f; } } } UIGraphics.BeginImageContextWithOptions(targetSize, false, 0.0f); var thumbnailRect = new RectangleF(thumbnailPoint, new SizeF(scaledWidth, scaledHeight)); sourceImage.Draw(thumbnailRect); newImage = UIGraphics.GetImageFromCurrentImageContext(); if (newImage == null) { Console.WriteLine("could not scale image"); } //pop the context to get back to the default UIGraphics.EndImageContext(); return newImage; } 

मैंने सैम वर्र्च की गाइड को तेज करने के लिए परिवर्तित कर दिया और यह मेरे लिए अच्छी तरह से काम किया, हालांकि अंतिम छवि में कुछ बहुत ही थोड़ा "स्क्वॉशिंग" है जिसे मैं हल नहीं कर सकता

 func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage { var ratio: CGFloat = 0 var delta: CGFloat = 0 var offset = CGPointZero if image.size.width > image.size.height { ratio = newSize.width / image.size.width delta = (ratio * image.size.width) - (ratio * image.size.height) offset = CGPointMake(delta / 2, 0) } else { ratio = newSize.width / image.size.height delta = (ratio * image.size.height) - (ratio * image.size.width) offset = CGPointMake(0, delta / 2) } let clipRect = CGRectMake(-offset.x, -offset.y, (ratio * image.size.width) + delta, (ratio * image.size.height) + delta) UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0) UIRectClip(clipRect) image.drawInRect(clipRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

यदि कोई उद्देश्य सी संस्करण चाहता है, तो उसकी वेबसाइट पर है

निम्नलिखित सरल कोड मेरे लिए काम किया

 [imageView setContentMode:UIViewContentModeScaleAspectFill]; [imageView setClipsToBounds:YES]; 
 scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0,0.0,ScreenWidth,ScreenHeigth)]; [scrollView setBackgroundColor:[UIColor blackColor]]; [scrollView setDelegate:self]; [scrollView setShowsHorizontalScrollIndicator:NO]; [scrollView setShowsVerticalScrollIndicator:NO]; [scrollView setMaximumZoomScale:2.0]; image=[image scaleToSize:CGSizeMake(ScreenWidth, ScreenHeigth)]; imageView = [[UIImageView alloc] initWithImage:image]; UIImageView* imageViewBk = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]]; [self.view addSubview:imageViewBk]; CGRect rect; rect.origin.x=0; rect.origin.y=0; rect.size.width = image.size.width; rect.size.height = image.size.height; [imageView setFrame:rect]; [scrollView setContentSize:[imageView frame].size]; [scrollView setMinimumZoomScale:[scrollView frame].size.width / [imageView frame].size.width]; [scrollView setZoomScale:[scrollView minimumZoomScale]]; [scrollView addSubview:imageView]; [[self view] addSubview:scrollView]; 

तो आप इस पर अपनी छवि में स्क्रीन शॉट्स ले सकते हैं

 float zoomScale = 1.0 / [scrollView zoomScale]; CGRect rect; rect.origin.x = [scrollView contentOffset].x * zoomScale; rect.origin.y = [scrollView contentOffset].y * zoomScale; rect.size.width = [scrollView bounds].size.width * zoomScale; rect.size.height = [scrollView bounds].size.height * zoomScale; CGImageRef cr = CGImageCreateWithImageInRect([[imageView image] CGImage], rect); UIImage *cropped = [UIImage imageWithCGImage:cr]; CGImageRelease(cr); 
 - (UIImage*)imageScale:(CGFloat)scaleFactor cropForSize:(CGSize)targetSize { targetSize = !targetSize.width?self.size:targetSize; UIGraphicsBeginImageContext(targetSize); // this will crop CGRect thumbnailRect = CGRectZero; thumbnailRect.size.width = targetSize.width*scaleFactor; thumbnailRect.size.height = targetSize.height*scaleFactor; CGFloat xOffset = (targetSize.width- thumbnailRect.size.width)/2; CGFloat yOffset = (targetSize.height- thumbnailRect.size.height)/2; thumbnailRect.origin = CGPointMake(xOffset,yOffset); [self drawInRect:thumbnailRect]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); if(newImage == nil) { NSLog(@"could not scale image"); } UIGraphicsEndImageContext(); return newImage; } 

काम के उदाहरण के नीचे: वाम छवि – (मूल छवि); स्केल x2 के साथ सही छवि

यहां छवि विवरण दर्ज करें

यदि आप छवि को स्केल करना चाहते हैं, लेकिन इसके फ्रेम (अनुपात) को बनाए रखना चाहते हैं, तो कॉल पद्धति इस प्रकार है:

 [yourImage imageScale:2.0f cropForSize:CGSizeZero]; 

ऐसा लगता है कि इस प्रश्न को आराम दिया गया है, लेकिन एक समाधान के लिए मेरी तलाश में कि मैं और अधिक आसानी से समझ सकता हूँ (और स्विफ्ट में लिखा), मैं इस पर पहुंचा (यहां पोस्ट की गई: यूआईमेज फसल कैसे करें? )


मैं एक पहलू अनुपात के आधार पर क्षेत्र से फसल करने में सक्षम होना चाहता था, और बाहरी सीमा सीमा के आधार पर एक आकार के पैमाने पर करना चाहता था। यहां मेरी विविधता है:

 import AVFoundation import ImageIO class Image { class func crop(image:UIImage, crop source:CGRect, aspect:CGSize, outputExtent:CGSize) -> UIImage { let sourceRect = AVMakeRectWithAspectRatioInsideRect(aspect, source) let targetRect = AVMakeRectWithAspectRatioInsideRect(aspect, CGRect(origin: CGPointZero, size: outputExtent)) let opaque = true, deviceScale:CGFloat = 0.0 // use scale of device's main screen UIGraphicsBeginImageContextWithOptions(targetRect.size, opaque, deviceScale) let scale = max( targetRect.size.width / sourceRect.size.width, targetRect.size.height / sourceRect.size.height) let drawRect = CGRect(origin: -sourceRect.origin * scale, size: image.size * scale) image.drawInRect(drawRect) let scaledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return scaledImage } } 

कुछ ऐसी चीजें हैं जिन्हें मुझे भ्रमित हुआ, फसल और आकार बदलने की अलग-अलग चिंताओं का फसल को रीक्ट की उत्पत्ति के साथ नियंत्रित किया जाता है जिसे आप आकर्षित करने के लिए पास करते हैं, और स्केलिंग को आकार के हिस्से द्वारा नियंत्रित किया जाता है। मेरे मामले में, मुझे स्रोत पर फसल काटने का आकार संबंधित करने की जरूरत थी, उसी अनुपात में मेरे आउटपुट रीसेट के लिए। पैमाने का कारक तब आउटपुट / इनपुट होता है, और इसे drawRect पर लागू किया जाना चाहिए (DrawInRect को पारित किया गया)

एक चेतावनी यह है कि यह दृष्टिकोण प्रभावी ढंग से मानता है कि जिस चित्र को आप चित्रित कर रहे हैं वह छवि संदर्भ से बड़ा है मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि आप फसल / ज़ूमिंग को संभालने के लिए इस कोड का उपयोग कर सकते हैं, लेकिन पैमाने पर पैरामीटर को स्पष्ट रूप से परिभाषित किया गया है, जो कि पहले से आयाम पैमाने पैरामीटर है। डिफ़ॉल्ट रूप से, UIKit स्क्रीन रिज़ोल्यूशन के आधार पर एक गुणक लागू करता है।

अंत में, यह ध्यान दिया जाना चाहिए कि यह UIKit दृष्टिकोण CoreGraphics / Quartz और कोर छवि दृष्टिकोण से उच्च स्तर है, और छवि उन्मुखीकरण मुद्दों को संभालना लगता है। यह भी उल्लेखनीय है कि यह बहुत तेज है, ImageIO के लिए दूसरा, यहां इस पोस्ट के अनुसार: http://nshipster.com/image-resizing/

स्विफ्ट संस्करण:

  static func imageWithImage(image:UIImage, newSize:CGSize) ->UIImage { UIGraphicsBeginImageContextWithOptions(newSize, true, UIScreen.mainScreen().scale); image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage } 

विलियम टी द्वारा तैनात तेजी के लिए सैम वर्र्च की मार्गदर्शिका का एक स्विफ्ट 3 संस्करण यहां दिया गया है।

 extension UIImage { static func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage? { var ratio: CGFloat = 0 var delta: CGFloat = 0 var offset = CGPoint.zero if image.size.width > image.size.height { ratio = newSize.width / image.size.width delta = (ratio * image.size.width) - (ratio * image.size.height) offset = CGPoint(x: delta / 2, y: 0) } else { ratio = newSize.width / image.size.height delta = (ratio * image.size.height) - (ratio * image.size.width) offset = CGPoint(x: 0, y: delta / 2) } let clipRect = CGRect(x: -offset.x, y: -offset.y, width: (ratio * image.size.width) + delta, height: (ratio * image.size.height) + delta) UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0) UIRectClip(clipRect) image.draw(in: clipRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } }