2017-01-13 20 views
7

मैंने UICropperViewController लिखा है और यह लैंडस्केप मोड में छवियों के लिए पूरी तरह से काम कर रहा है। पोर्ट्रेट मोड में छवियों में एक बड़ी समस्या है। जब यह हम इस स्थिति मिल गया चित्र छवियों की बात आती हैसीजीआईमेज क्यों है? छवि को घूर्णन करना?

enter image description here

अब:

enter image description here

फसल परिणाम है: निम्न चित्र एक पीले रंग की फसल फ्रेम के साथ एक साधारण तस्वीर से पता चलता

enter image description here

निम्नलिखित परिणाम के साथ:

enter image description here

तो क्या यहाँ happend? मूल छवि स्वचालित रूप से बाईं ओर घूमती है।

मैं बहुत शोध किया और मूल रूप से दो सुझाव नहीं मिले: फसल और इसे फिर से स्थापित करने से पहले छवि उन्मुखीकरण

सुझाव 1

सहेजें।

func didTapCropButton(sender: AnyObject) { 
    let originalOrientation = self.imageView.image?.imageOrientation; 

    // raw value of originalOrientation is `3` so its rotated to the right 

    let croppedCGImage = self.imageView.image?.cgImage?.cropping(to: self.cropArea); 

    // create a cropped cgImage 

    let croppedImage = UIImage(cgImage: croppedCGImage!, scale: (self.imageView.image?.scale)!, orientation: (originalOrientation)!); 

    // create the UIImage with the result from cgImage cropping and original orientation 

    if (self.callback != nil) { 
     self.callback.croppingDone(image: croppedImage); 
    } 

    self.dismiss(animated: true, completion: nil); 
} 

लेकिन परिणाम है:

enter image description here

तो स्पष्ट रूप से यह सुझाव है क्योंकि यह केवल पहले से ही फसली छवि वापस घूर्णन कर रहा है काम नहीं करता।

सुझाव 2

अभिविन्यास फिक्सिंग। मैं वादा है कि यह त्रुटि को ठीक होगा साथ कोड का निम्न भाग पाया:

func didTapCropButton(sender: AnyObject) { 
    let image = self.imageView.image?.fixOrientation(); 
    let croppedCGImage = image?.cgImage?.cropping(to: self.cropArea); 
    let croppedImage = UIImage(cgImage: croppedCGImage!); 

    if (self.callback != nil) { 
     self.callback.croppingDone(image: croppedImage); 
    } 

    self.dismiss(animated: true, completion: nil); 
} 

extension UIImage { 

    /// Extension to fix orientation of an UIImage without EXIF 
    func fixOrientation() -> UIImage { 

     guard let cgImage = cgImage else { return self } 

     if imageOrientation == .up { return self } 

     var transform = CGAffineTransform.identity 

     switch imageOrientation { 

     case .down, .downMirrored: 
      transform = transform.translatedBy(x: size.width, y: size.height) 
      transform = transform.rotated(by: CGFloat(M_PI)) 

     case .left, .leftMirrored: 
      transform = transform.translatedBy(x: size.width, y: 0) 
      transform = transform.rotated(by: CGFloat(M_PI_2)) 

     case .right, .rightMirrored: 
      transform = transform.translatedBy(x: 0, y: size.height) 
      transform = transform.rotated(by: CGFloat(-M_PI_2)) 

     case .up, .upMirrored: 
      break 
     } 

     switch imageOrientation { 

     case .upMirrored, .downMirrored: 
      transform.translatedBy(x: size.width, y: 0) 
      transform.scaledBy(x: -1, y: 1) 

     case .leftMirrored, .rightMirrored: 
      transform.translatedBy(x: size.height, y: 0) 
      transform.scaledBy(x: -1, y: 1) 

     case .up, .down, .left, .right: 
      break 
     } 

     if let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: cgImage.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) { 

      ctx.concatenate(transform) 

      switch imageOrientation { 

      case .left, .leftMirrored, .right, .rightMirrored: 
       ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width)) 

      default: 
       ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) 
      } 

      if let finalImage = ctx.makeImage() { 
       return (UIImage(cgImage: finalImage)) 
      } 
     } 

     // something failed -- return original 
     return self 
    } 
} 

लेकिन यह एक गलत फसल क्षेत्र का परिणाम है।

enter image description here

तो क्या है कि समस्या के लिए एक वास्तविक समाधान हो सकता है: परिणाम अब कुछ की तरह हो सकता है? वैसे भी, अगर उपयोगकर्ता इसे नहीं चाहता है तो छवि को स्वचालित रूप से घूर्णन करने की क्या समझ है? क्या यह स्वचालित रोटेशन अक्षम करना संभव है?

संपादित

मेरी क्रॉपर का पूरा स्रोत:

import Foundation 
import UIKit 

protocol CropperCallback { 

    func croppingDone(image: UIImage); 

    func croppingCancelled(); 
} 

class CropperViewController : UIViewController { 
    @IBOutlet var imageView: UIImageView!; 
    var imageViewScaleCurrent: CGFloat! = 1.0; 
    var imageViewScaleMin: CGFloat! = 0.5; 
    var imageViewScaleMax: CGFloat! = 5.0; 
    @IBOutlet var cropAreaView: CropAreaView!; 
    @IBOutlet weak var cropAreaViewConstraintWidth: NSLayoutConstraint! 
    @IBOutlet weak var cropAreaViewConstraintHeight: NSLayoutConstraint! 
    @IBOutlet var btnCrop: UIButton!; 
    @IBOutlet var btnCancel: UIButton!; 

    var callback: CropperCallback! = nil; 
    var image: UIImage! = nil; 
    var imageOriginalWidth: CGFloat!; 
    var imageOriginalHeight: CGFloat!; 
    var cropWidth: CGFloat! = 287;/ 
    var cropHeight: CGFloat! = 292; 
    var cropHeightFix: CGFloat! = 1.0; 
    var cropArea: CGRect { 

     get { 
      let factor = self.imageView.image!.size.width/self.view.frame.width; 
      let scale = 1/self.imageViewScaleCurrent; 
      let x = (self.cropAreaView.frame.origin.x - self.imageView.frame.origin.x) * scale * factor; 
      let y = (self.cropAreaView.frame.origin.y - self.imageView.frame.origin.y) * scale * factor; 
      let width = self.cropAreaView.frame.size.width * scale * factor; 
      let height = self.cropAreaView.frame.size.height * scale * factor; 

      return CGRect(x: x, y: y, width: width, height: height); 
     } 
    } 

    static func storyboardInstance() -> CropperViewController? { 
     let storyboard = UIStoryboard(name: String(describing: NSStringFromClass(CropperViewController.classForCoder()).components(separatedBy: ".").last!), bundle: nil); 

     return storyboard.instantiateInitialViewController() as? CropperViewController; 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad(); 

     /* 
     if (self.image.imageOrientation != .up) { 
      self.image = UIImage(cgImage: self.image.cgImage!, scale: self.image.scale, orientation: UIImageOrientation(rawValue: 0)!); 
     } 
     */ 

     self.imageView.image = self.image; 
     self.imageView.isUserInteractionEnabled = true; 
     self.imageView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(_:)))); 
     self.imageView.addGestureRecognizer(UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch(_:)))); 

     self.cropAreaViewConstraintWidth.constant = self.cropWidth; 
     self.cropAreaViewConstraintHeight.constant = self.cropHeight; 

     self.btnCrop.addTarget(self, action: #selector(self.didTapCropButton), for: UIControlEvents.touchUpInside); 
     self.btnCancel.addTarget(self, action: #selector(self.didTapCancelButton), for: UIControlEvents.touchUpInside); 
    } 

    override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews(); 

     let imageOriginalRect = self.getRectOfImageInImageView(imageView: self.imageView); 

     self.imageOriginalWidth = imageOriginalRect.size.width; 
     self.imageOriginalHeight = imageOriginalRect.size.height; 

     self.createOverlay(); 
    } 

    func createOverlay() { 
     let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)); 
     let pathRect = UIBezierPath(rect: CGRect(x: self.cropAreaView.frame.origin.x, y: self.cropAreaView.frame.origin.y, width: self.cropWidth, height: self.cropHeight)); 

     path.append(pathRect); 
     path.usesEvenOddFillRule = true; 

     let fillLayer = CAShapeLayer(); 
     fillLayer.path = path.cgPath; 
     fillLayer.fillRule = kCAFillRuleEvenOdd; 
     fillLayer.fillColor = UIColor.white.cgColor; 
     fillLayer.opacity = 0.1; 

     self.view.layer.addSublayer(fillLayer); 
    } 

    func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) { 
     if gestureRecognizer.state == .began || gestureRecognizer.state == .changed { 
      let rect = self.getRectOfImageInImageView(imageView: self.imageView); 
      let xImage = rect.origin.x; 
      let yImage = rect.origin.y; 
      let widthImage = rect.size.width; 
      let heightImage = rect.size.height; 

      let xCropView = self.cropAreaView.frame.origin.x; 
      let yCropView = self.cropAreaView.frame.origin.y; 
      let widthCropView = self.cropAreaView.frame.size.width; 
      let heightCropView = self.cropAreaView.frame.size.height; 

      let translation = gestureRecognizer.translation(in: self.view); 

      var x: CGFloat; 
      var y: CGFloat; 

      if (translation.x > 0) { 
       if (!(xImage >= xCropView)) { 
        x = gestureRecognizer.view!.center.x + translation.x; 
       } else { 
        x = gestureRecognizer.view!.center.x; 
       } 
      } else if (translation.x < 0) { 
       if (!((xImage + widthImage) <= (xCropView + widthCropView))) { 
        x = gestureRecognizer.view!.center.x + translation.x; 
       } else { 
        x = gestureRecognizer.view!.center.x; 
       } 
      } else { 
       x = gestureRecognizer.view!.center.x; 
      } 

      if (translation.y > 0) { 
       if (!(yImage >= (yCropView - self.cropHeightFix))) { 
        y = gestureRecognizer.view!.center.y + translation.y; 
       } else { 
        y = gestureRecognizer.view!.center.y; 
       } 
      } else if (translation.y < 0) { 
       if (!((yImage + heightImage) <= (yCropView + heightCropView + self.cropHeightFix))) { 
        y = gestureRecognizer.view!.center.y + translation.y; 
       } else { 
        y = gestureRecognizer.view!.center.y; 
       } 
      } else { 
       y = gestureRecognizer.view!.center.y; 
      } 

      gestureRecognizer.view!.center = CGPoint(x: x, y: y); 
      gestureRecognizer.setTranslation(CGPoint.zero, in: self.view); 

      self.fixImageViewPosition(); 
     } 
    } 

    func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) { 
     if let view = gestureRecognizer.view { 
      let widthCropView = self.cropAreaView.frame.size.width; 
      let heightCropView = self.cropAreaView.frame.size.height; 

      if (((self.imageViewScaleCurrent * gestureRecognizer.scale * self.imageOriginalWidth) > widthCropView) 
       && ((self.imageViewScaleCurrent * gestureRecognizer.scale * self.imageOriginalHeight) > (heightCropView + (2 * self.cropHeightFix))) 
       && ((self.imageViewScaleCurrent * gestureRecognizer.scale) < self.imageViewScaleMax)) { 

       self.imageViewScaleCurrent = self.imageViewScaleCurrent * gestureRecognizer.scale; 

       view.transform = CGAffineTransform(scaleX: self.imageViewScaleCurrent, y: self.imageViewScaleCurrent); 
      } 

      gestureRecognizer.scale = 1.0; 

      self.fixImageViewPosition(); 
     } 
    } 

    func fixImageViewPosition() { 
     let rect = self.getRectOfImageInImageView(imageView: self.imageView); 
     let xImage = rect.origin.x; 
     let yImage = rect.origin.y; 
     let widthImage = rect.size.width; 
     let heightImage = rect.size.height; 

     let xCropView = self.cropAreaView.frame.origin.x; 
     let yCropView = self.cropAreaView.frame.origin.y; 
     let widthCropView = self.cropAreaView.frame.size.width; 
     let heightCropView = self.cropAreaView.frame.size.height; 

     if (xImage > xCropView) { 
      self.imageView.frame = CGRect(x: xCropView, y: self.imageView.frame.origin.y, width: widthImage, height: heightImage); 
     } 

     if ((xImage + widthImage) < (xCropView + widthCropView)) { 
      self.imageView.frame = CGRect(x: ((xCropView + widthCropView) - widthImage), y: self.imageView.frame.origin.y, width: widthImage, height: heightImage); 
     } 

     if (yImage > yCropView) { 
      self.imageView.frame = CGRect(x: self.imageView.frame.origin.x, y: (yCropView - self.cropHeightFix), width: widthImage, height: heightImage); 
     } 

     if ((yImage + heightImage) < (yCropView + heightCropView + self.cropHeightFix)) { 
      self.imageView.frame = CGRect(x: self.imageView.frame.origin.x, y: ((yCropView + heightCropView + self.cropHeightFix) - heightImage), width: widthImage, height: heightImage); 
     } 
    } 

    func getRectOfImageInImageView(imageView: UIImageView) -> CGRect { 
     let imageViewSize = imageView.frame.size; 
     let imageSize = imageView.image!.size; 

     let scaleW = imageViewSize.width/imageSize.width; 
     let scaleH = imageViewSize.height/imageSize.height; 
     let aspect = min(scaleW, scaleH); 

     var imageRect = CGRect(x: 0, y: 0, width: (imageSize.width * aspect), height: (imageSize.height * aspect)); 

     imageRect.origin.x = (imageViewSize.width - imageRect.size.width)/2; 
     imageRect.origin.y = (imageViewSize.height - imageRect.size.height)/2; 

     imageRect.origin.x += imageView.frame.origin.x; 
     imageRect.origin.y += imageView.frame.origin.y; 

     return imageRect; 
    } 

    func getCGImageWithCorrectOrientation(_ image : UIImage) -> CGImage { 
     if (image.imageOrientation == UIImageOrientation.up) { 
      return image.cgImage!; 
     } 

     var transform : CGAffineTransform = CGAffineTransform.identity; 

     switch (image.imageOrientation) { 
     case UIImageOrientation.right, UIImageOrientation.rightMirrored: 
      transform = transform.translatedBy(x: 0, y: image.size.height); 
      transform = transform.rotated(by: CGFloat(-1.0 * M_PI_2)); 
      break; 
     case UIImageOrientation.left, UIImageOrientation.leftMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: 0); 
      transform = transform.rotated(by: CGFloat(M_PI_2)); 
      break; 
     case UIImageOrientation.down, UIImageOrientation.downMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: image.size.height); 
      transform = transform.rotated(by: CGFloat(M_PI)); 
      break; 
     default: 
      break; 
     } 

     switch (image.imageOrientation) { 
     case UIImageOrientation.rightMirrored, UIImageOrientation.leftMirrored: 
      transform = transform.translatedBy(x: image.size.height, y: 0); 
      transform = transform.scaledBy(x: -1, y: 1); 
      break; 
     case UIImageOrientation.downMirrored, UIImageOrientation.upMirrored: 
      transform = transform.translatedBy(x: image.size.width, y: 0); 
      transform = transform.scaledBy(x: -1, y: 1); 
      break; 
     default: 
      break; 
     } 

     let contextWidth : Int; 
     let contextHeight : Int; 

     switch (image.imageOrientation) { 
     case UIImageOrientation.left, UIImageOrientation.leftMirrored, 
      UIImageOrientation.right, UIImageOrientation.rightMirrored: 
      contextWidth = (image.cgImage?.height)!; 
      contextHeight = (image.cgImage?.width)!; 
      break; 
     default: 
      contextWidth = (image.cgImage?.width)!; 
      contextHeight = (image.cgImage?.height)!; 
      break; 
     } 

     let context : CGContext = CGContext(data: nil, width: contextWidth, height: contextHeight, 
              bitsPerComponent: image.cgImage!.bitsPerComponent, 
              bytesPerRow: image.cgImage!.bytesPerRow, 
              space: image.cgImage!.colorSpace!, 
              bitmapInfo: image.cgImage!.bitmapInfo.rawValue)!; 

     context.concatenate(transform); 
     context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: CGFloat(contextWidth), height: CGFloat(contextHeight))); 

     let cgImage = context.makeImage(); 

     return cgImage!; 
    } 

    func didTapCropButton(sender: AnyObject) { 
     let fixedImage = self.getCGImageWithCorrectOrientation(self.imageView.image!); 

     // let image = self.imageView.image?.fixOrientation(); 

     let croppedCGImage = fixedImage.cropping(to: self.cropArea); 
     let croppedImage = UIImage(cgImage: croppedCGImage!); 

     if (self.callback != nil) { 
      self.callback.croppingDone(image: croppedImage); 
     } 

     self.dismiss(animated: true, completion: nil); 
    } 

    func didTapCancelButton(sender: AnyObject) { 
     if (self.callback != nil) { 
      self.callback.croppingCancelled(); 
     } 

     self.dismiss(animated: true, completion: nil); 
    } 
} 

extension UIImageView { 

    func imageFrame() -> CGRect { 
     let imageViewSize = self.frame.size; 

     guard let imageSize = self.image?.size else { 
      return CGRect.zero; 
     } 

     let imageRatio = imageSize.width/imageSize.height; 
     let imageViewRatio = imageViewSize.width/imageViewSize.height; 

     if (imageRatio < imageViewRatio) { 
      let scaleFactor = imageViewSize.height/imageSize.height; 
      let width = imageSize.width * scaleFactor; 
      let topLeftX = (imageViewSize.width - width) * 0.5; 

      return CGRect(x: topLeftX, y: 0, width: width, height: imageViewSize.height); 
     } else { 
      let scaleFactor = imageViewSize.width/imageSize.width; 
      let height = imageSize.height * scaleFactor; 
      let topLeftY = (imageViewSize.height - height) * 0.5; 

      return CGRect(x: 0, y: topLeftY, width: imageViewSize.width, height: height); 
     } 
    } 
} 

extension UIImage { 

    // Extension to fix orientation of an UIImage without EXIF 

    func fixOrientation() -> UIImage { 
     guard let cgImage = self.cgImage else { 
      return self; 
     } 

     if self.imageOrientation == .up { 
      return self; 
     } 

     var transform = CGAffineTransform.identity; 

     switch self.imageOrientation { 
     case .down, .downMirrored: 
      transform = transform.translatedBy(x: self.size.width, y: self.size.height); 
      transform = transform.rotated(by: CGFloat(M_PI)); 
     case .left, .leftMirrored: 
      transform = transform.translatedBy(x: self.size.width, y: 0); 
      transform = transform.rotated(by: CGFloat(M_PI_2)); 
     case .right, .rightMirrored: 
      transform = transform.translatedBy(x: 0, y: self.size.height); 
      transform = transform.rotated(by: CGFloat(-M_PI_2)); 
     case .up, .upMirrored: 
      break; 
     } 

     switch self.imageOrientation { 
     case .upMirrored, .downMirrored: 
      transform.translatedBy(x: self.size.width, y: 0); 
      transform.scaledBy(x: -1, y: 1); 
     case .leftMirrored, .rightMirrored: 
      transform.translatedBy(x: self.size.height, y: 0); 
      transform.scaledBy(x: -1, y: 1); 
     case .up, .down, .left, .right: 
      break; 
     } 

     if let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: cgImage.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) { 
      ctx.concatenate(transform); 

      switch self.imageOrientation { 
      case .left, .leftMirrored, .right, .rightMirrored: 
       ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width)); 
      default: 
       ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)); 
      } 

      if let finalImage = ctx.makeImage() { 
       return (UIImage(cgImage: finalImage)); 
      } 
     } 

     // something failed -- return original 
     return self; 
    } 
} 
+0

वैसे, http://stackoverflow.com/questions/158914/cropping-an-uiimage/14712184#14712184 को एक बहुत ही सरल कार्यान्वयन के लिए देखें जो पूरी छवि के बजाय फसल रेक्ट को घुमाता है। इसके अलावा, http://stackoverflow.com/a/18602671/669586 एक बहुत ही सरल समाधान है। – Sulthan

+0

क्या आपको अपने प्रश्न का उत्तर मिला? –

उत्तर

4

आप scale और orientation गुण को समझना होगा।

आपका सुझाव 1 (मूल छवि के अभिविन्यास का उपयोग करें) स्पष्ट रूप से एक सही सुझाव है और यह काम करेगा, अगर आप अपने cropArea को घूमने और स्केल करने में सक्षम थे।

आपका सुझाव 2 रोटेशन को संभालने के लिए अच्छा है लेकिन आपको अभी भी स्केलcropArea होना है। वर्तमान में आप पैमाने पर संभाल नहीं रहे हैं।

(मामूली नोट, घूर्णन cropArea शायद पूरी छवि को घूर्णन करने से बेहतर प्रदर्शन होगा, https://stackoverflow.com/a/14712184/669586 देखें)।

आप के लिए है:

  1. स्केल (गुणा) cropArea छवि के पैमाने से।
  2. जब परिणाम

उदाहरण के लिए बनाने, यदि आपका UIImage आकार 200x100 है और यह 2x पैमाने पर (यह एक रेटिना छवि है) है, अपने cgImage आकार 400x200 होगा लेकिन आप अभी भी काम कर रहे हैं मूल छवि पैमाने का प्रयोग करें 200x100 के अंदर एक फसल क्षेत्र के साथ!

की तर्ज पर

कुछ:

func didTapCropButton(sender: AnyObject) { 
    guard let image = self.imageView.image else { 
     return 
    } 

    let cgImage = self.getCGImageWithCorrectOrientation(image); 

    let scaledCropArea = CGRect(
     x: self.cropArea.x * image.scale, 
     y: self.cropArea.y * image.scale, 
     width: self.cropArea.width * image.scale, 
     height: self.cropArea.height * image.scale 
    ) 

    let croppedCGImage = cgImage.cropping(to: scaledCropArea) 
    let croppedImage = UIImage(cgImage: croppedCGImage!, scale: image.scale, orientation: .up) 

    if (self.callback != nil) { 
     self.callback.croppingDone(image: croppedImage) 
    } 

    self.dismiss(animated: true, completion: nil) 
} 

स्वत: रोटेशन और UIImage में बदल देती है तो बस एक अनुकूलन कर रहे हैं। इस अनुकूलन के लिए धन्यवाद, एकाधिक छवियां एक ही भंडारण (समान स्मृति डेटा) साझा कर सकती हैं। अनुकूलन पहले से ही आपके एसेट लोडर में किया गया है और आप इसे अक्षम नहीं कर सकते हैं।

इसके अलावा, कृपया https://stackoverflow.com/a/18602671/669586 को एक सरल और सुरक्षित कार्यान्वयन के लिए देखें।

+0

स्केलिंग सुझाव 1 के साथ समस्या प्रतीत नहीं होती है। परिणाम एक परिदृश्य फसल वाली तस्वीर है जहां यह एक चित्रित चित्रित चित्र होना चाहिए। सुझाव 1 के साथ ऐसा होता है: चित्र से परिदृश्य, फसल, घूमने के लिए घुमाएं। यदि नहीं, तो मैं समझ नहीं पा रहा हूं कि आपका क्या मतलब है। – Mulgard

+0

@ मल्गार्ड मैंने गलत देखा। 'फसल एरिया' घुमाया जाना चाहिए। मैं आपके दूसरे सुझाव का अधिक विस्तार से निरीक्षण करूंगा। – Sulthan

+0

@ मल्गार्ड अपने कोड को देखने के बाद, मुझे लगता है कि मेरा मूल विचार सही था। आपको पैमाने को अपडेट करना होगा। – Sulthan

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