【问题标题】:Determining the center of a zoomed and panned image in UIScrollview在 UIScrollview 中确定缩放和平移图像的中心
【发布时间】:2014-08-05 08:36:19
【问题描述】:

我正在为 iPhone 构建一个照片应用程序,它允许用户使用相机拍照或从相机胶卷中抓取一张照片,然后在 UIScrollView 中根据需要平移和缩放此图像。然后用户点击一个按钮来保存图像。我在返回嵌入在滚动视图中的图像视图的可见区域的确切中心的关键方法时遇到问题。我需要这种方法来允许设备屏幕尺寸的变化(即 iPhone 4 vs 5),以及源图像的大小、纵横比和缩放比例的变化。

作为一个例子,我需要让它为以下工作:

  • 屏幕尺寸为 320 X 568 的 iPhone 5
  • Scrollview 帧大小为 320 X 568
  • 尺寸为 380 宽和 284 高的图像
  • 缩放比例为 3.0

或者,我也需要它为此工作:

  • 屏幕尺寸为 320 X 480 的 iPhone 4
  • Scrollview 帧大小为 320 X 480
  • 尺寸为 640 宽和 1048 高的图像
  • 缩放比例为 1.3

以下是我当前的代码,它试图解释屏幕尺寸和图像尺寸的变化,但它不适用于 iPhone 4 和 5,以及所有类型的图像,例如纵向或横向格式。有没有更简单的方法来获取滚动视图可见部分的中心点?我需要更清楚地了解如何解释和操作视图的属性,例如 bounds.origin 和 bounds.size 以及在滚动视图中使用内容大小和缩放比例。

我查看了各种类似的问题,但这些问题似乎都不能充分说明设备或图像纵横比或大小的所有变化。任何帮助将不胜感激!

类似的问题

How can I determine the area currently visible in a scrollview and determine the center?

Getting the right coordinates of the visible part of a UIImage inside of UIScrollView

- (CGPoint)centerOfVisibleFrame:(UIImage *)image inScrollView:(UIScrollView *)scrollView
{
    CGPoint frameCenter;

    CGFloat zoomScale = scrollView.zoomScale;

    // First determine the dimensions of the device
    CGSize deviceFrameSize = [UIScreen mainScreen].bounds.size;

    // Need to determine the scale factor for adjusting the image to full width/full height
    CGFloat imageDeviceAspectFitScale;

    // Compare the aspect ratio (height / width) of the device to the aspect ratio of the image
    CGFloat deviceAspectRatio = deviceFrameSize.height / deviceFrameSize.width;
    CGFloat imageAspectRatio = image.size.height / image.size.width;

    // If the device's aspect ratio is greater than the image aspect ratio
    if (deviceAspectRatio > imageAspectRatio)
    {
        // Set the imageDeviceAspectFitScale for full width
        imageDeviceAspectFitScale = image.size.width / deviceFrameSize.width;
    }
    // Otherwise the image's aspect ratio is greater than the device aspect ratio
    else
    {
        // Set the imageDeviceAspectFitScale for full height
        imageDeviceAspectFitScale = image.size.height / deviceFrameSize.height;
    }

    // Create the frame for the image at full width or full height
    CGSize imageAspectFitSize;
    imageAspectFitSize.width = image.size.width / imageDeviceAspectFitScale;
    imageAspectFitSize.height = image.size.height / imageDeviceAspectFitScale;

    // Calculate the vertical and horizontal offset to adjust the coordinates of the
    // image center to account for greater device height or device width
    CGFloat verticalOffset = deviceFrameSize.height - imageAspectFitSize.height;
    CGFloat horizontalOffset = deviceFrameSize.width - imageAspectFitSize.width;

    if (self.debug) NSLog(@"verticalOffset = %f horizontalOffset = %f", verticalOffset, horizontalOffset);

    if (self.debug) NSLog(@"image.size.width: %f image.size.height: %f", image.size.width, image.size.height);

    if (self.debug) NSLog(@"scrollView.frame.size w: %f h: %f", scrollView.frame.size.width, scrollView.frame.size.height);

    if (self.debug) NSLog(@"scrollView.bounds.size.width: %f scrollView.bounds.size.height: %f",
                          scrollView.bounds.size.width, scrollView.bounds.size.height);

    if (self.debug) NSLog(@"scrollView.contentSize w=%f h=%f", scrollView.contentSize.width, scrollView.contentSize.height);

    // imageRect represents the coordinate space for the image, adjusted for zoom scale
    CGRect imageRect;

    // First use the visible frame's origin to determine the top left corner of the visible rectangle
    imageRect.origin.x = scrollView.contentOffset.x;
    imageRect.origin.y = scrollView.contentOffset.y;

    if (self.debug) NSLog(@"imageRect.origin x = %f y = %f", imageRect.origin.x, imageRect.origin.y);

    // Adjust the image rect for zoom - Multiply by zoom scale
    imageRect.size.width = image.size.width * zoomScale;
    imageRect.size.height = image.size.height * zoomScale;

    if (self.debug) NSLog(@"Zoomed imageRect.size width = %f height = %f", imageRect.size.width, imageRect.size.height);

    // Then scale the image down to fit into the device frame
    // Divide by the image device aspect fit scale
    imageRect.size.width = imageRect.size.width / imageDeviceAspectFitScale;
    imageRect.size.height = imageRect.size.height / imageDeviceAspectFitScale;

    if (self.debug) NSLog(@"CVF Aspect fit imageRect.size width = %f height = %f", imageRect.size.width, imageRect.size.height);

    // Then calculate the frame center by using the x and y dimensions of the DEVICE frame
    frameCenter.x = imageRect.origin.x + (deviceFrameSize.width / 2);
    frameCenter.y = imageRect.origin.y + (deviceFrameSize.height / 2);

    // Scale back to original image dimensions from zoom
    frameCenter.x = frameCenter.x / zoomScale;
    frameCenter.y = frameCenter.y / zoomScale;

    if (self.debug) NSLog(@"frameCenter.x = %f frameCenter.y = %f", frameCenter.x, frameCenter.y);

    // Scale back up for the aspect fit scale
    frameCenter.x = frameCenter.x * imageDeviceAspectFitScale;
    frameCenter.y = frameCenter.y * imageDeviceAspectFitScale;

    // Correct the coordinates for horizontal and vertical offset
    frameCenter.x = frameCenter.x - (horizontalOffset);
    frameCenter.y = frameCenter.y - (verticalOffset);

    if (self.debug) NSLog(@"CVF frameCenter.x = %f frameCenter.y = %f", frameCenter.x, frameCenter.y);

    return frameCenter;


}

【问题讨论】:

    标签: ios iphone objective-c uiscrollview


    【解决方案1】:

    基本上这会给你滚动视图的可见矩形。

    CGRect visibleRect = [yourScrollView convertRect:yourScrollView.bounds toView:yourImageview];
    

    CGRect visibleRect;
    visibleRect.origin = scrollView.contentOffset;
    visibleRect.size = scrollView.frame.size;
    

    请查看此问题和答案以获取更多详细信息。 Getting the visible rect of an UIScrollView's content.

    只要您知道矩形,您就可以轻松计算中心点。

    【讨论】:

    • 感谢您的回复。我仍在尝试了解视图几何,所以请原谅我的菜鸟问题,但是此答案中 visibleRect 的属性位于滚动视图的坐标空间中,不考虑缩放比例,对吗?如果该方法需要给我原始图像坐标空间中的精确点,除了缩放原点和大小以进行缩放之外,我还需要做些什么吗?
    • 点击按钮部分不清楚您的问题。当用户点击您要保存图像的按钮时,图像的哪个部分,可见部分还是什么?
    • 啊,对不起。当用户单击保存时,我希望应用程序剪切图像的圆形部分,其中心位于可见部分的正中间。这个圆形夹子的直径将是屏幕宽度的 90%。所以我需要这个方法返回的是,例如,给定一个 640 X 1048 的图像,在这个 640 X 1048 坐标空间中所选圆形段的 center 的 x 和 y 坐标。
    猜你喜欢
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2016-07-22
    • 1970-01-01
    • 2012-12-13
    • 2011-06-25
    相关资源
    最近更新 更多