简体   繁体   English

在UIImageView中移动UIImage

[英]Move UIImage inside UIImageView

I have an UIImageView (red squares) that will display a UIImage that must be scaled (I can receive images greater or smaller that the UIImageView ). 我有一个UIImageView (红色方块),它将显示一个必须缩放的UIImage (我可以接收比UIImageView更大或更小的图像)。 After scaling it, the showed part of the UIImage is the center of it. 缩放后, UIImage的显示部分就是它的中心。

What I need is to show the part of the image in the blue squares, how can I archive it? 我需要的是在蓝色方块中显示图像的一部分,我该如何存档?

I'm only able to get the image size (height and width), but it display the original size, when it's supposed to be the scaled one. 我只能获得图像大小(高度和宽度),但它显示原始大小,当它应该是缩放的大小。

self.viewIm = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 120, 80)];
self.viewIm.backgroundColor = [UIColor greenColor];
self.viewIm.layer.borderColor = [UIColor redColor].CGColor;
self.viewIm.layer.borderWidth = 5.0;
UIImage *im = [UIImage imageNamed:@"benjen"];
self.viewIm.image = im;
self.viewIm.contentMode = UIViewContentModeScaleAspectFill;
//    self.viewim.clipsToBounds = YES;
[self.view addSubview:self.viewIm];

在此输入图像描述

To do what you're trying to do, I'd recommend looking into CALayer 's contentsRect property. 为了做你想做的事情,我建议你查看CALayercontentsRect属性。

Since seeing your answer, I've been trying to work out the proper solution for a while, but the mathematics escapes me because contentsRect: 'sx and y parameters seem sort of mysterious... But here's some code that may point you in the right direction... 既然看到了你的答案,我一直试图找出适当的解决方案一段时间,但数学逃脱了我因为contentsRect: 'sx和y参数似乎有点神秘......但是这里的一些代码可能会指向你正确的方向......

float imageAspect = self.imageView.image.size.width/self.imageView.image.size.height;
float imageViewAspect = self.imageView.frame.size.width/self.imageView.frame.size.height;

if (imageAspect > imageViewAspect) {
    float scaledImageWidth = self.imageView.frame.size.height * imageAspect;
    float offsetWidth = -((scaledImageWidth-self.imageView.frame.size.width)/2);
    self.imageView.layer.contentsRect = CGRectMake(offsetWidth/self.imageView.frame.size.width, 0.0, 1.0, 1.0);
} else if (imageAspect < imageViewAspect) {
    float scaledImageHeight = self.imageView.frame.size.width * imageAspect;
    float offsetHeight = ((scaledImageHeight-self.imageView.frame.size.height)/2);
    self.imageView.layer.contentsRect = CGRectMake(0.0, offsetHeight/self.imageView.frame.size.height, 1.0, 1.0);
}

Try something like this: 尝试这样的事情:

CGRect cropRect = CGRectMake(0,0,200,200);
CGImageRef imageRef = CGImageCreateWithImageInRect([ImageToCrop CGImage],cropRect);
UIImage *image = [UIImage imageWithCGImage:imageRef]; 
CGImageRelease(imageRef);

I found a very good approximation on this answer . 我发现这个答案非常接近。 In that, the category resize the image, and use the center point to crop after that. 其中,类别调整图像大小,然后使用中心点进行裁剪。 I adapt it to crop using (0,0) as origin point. 我使用(0,0)作为原点来适应它。 As I don't really need a category, I use it as a single method. 因为我不需要类别,所以我将它用作单一方法。

- (UIImage *)imageByScalingAndCropping:(UIImage *)image forSize:(CGSize)targetSize {
    UIImage *sourceImage = image;
    UIImage *newImage = nil;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetSize.width;
    CGFloat scaledHeight = targetSize.height;

    if (CGSizeEqualToSize(image.size, targetSize) == NO) {
        if ((targetSize.width / image.size.width) > (targetSize.height / image.size.height)) {
            scaleFactor = targetSize.width / image.size.width; // scale to fit height
        } else {
            scaleFactor = targetSize.height / image.size.height; // scale to fit width
        }

        scaledWidth  = image.size.width * scaleFactor;
        scaledHeight = image.size.height * scaleFactor;
    }

    UIGraphicsBeginImageContext(targetSize); // this will crop

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = CGPointZero;
    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;
}

And my call is something like this: 我的电话是这样的:

self.viewIm = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 120, 80)];
self.viewIm.image = [self imageByScalingAndCropping:[UIImage imageNamed:@"benjen"] forSize:CGSizeMake(120, 80)];
[self.view addSubview:self.viewIm];

I've spent some time on this and finally created a Swift 3.2 solution (based on one of my answers on another thread, as well as one of the answers above). 我花了一些时间在这上面,最后创建了一个Swift 3.2解决方案(基于我在另一个主题上的一个答案,以及上面的一个答案)。 This code only allows for Y translation of the image, but with some tweaks anyone should be able to add horizontal translation as well ;) 此代码仅允许图像的Y转换,但通过一些调整,任何人都应该能够添加水平转换;)

let yOffset: CGFloat = 20
myImageView.contentMode = .scaleAspectFill

//scale image to fit the imageView's width (maintaining aspect ratio), but allow control over the image's Y position
UIGraphicsBeginImageContextWithOptions(myImageView.frame.size, myImageView.isOpaque, 0.0)
let ratio = myImage.size.width / myImage.size.height
let newHeight = myImageView.frame.width / ratio
let rect = CGRect(x: 0, y: -yOffset, width: myImageView.frame.width, height: newHeight)
myImage.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext() ?? myImage
UIGraphicsEndImageContext()

//set the new image
myImageView.image = newImage

Now you can adjust how far down or up you need the image to be by changing the yOffset . 现在,您可以通过更改yOffset来调整图像所需的向下或向上的yOffset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM