【问题标题】:UIImage: Resize, then CropUIImage:调整大小,然后裁剪
【发布时间】:2010-10-10 20:58:54
【问题描述】:

这几天我一直在用自己的脸来抨击这个问题,尽管我一直觉得我正处于启示的边缘,但我根本无法实现我的目标。

我认为,在我的设计的概念阶段提前,从 iPhone 的相机或库中抓取图像,将其缩小到指定的高度,使用相当于 Aspect Fill 选项(完全在代码中),然后裁剪任何不适合传递的 CGRect 的内容。

从相机或库中获取原始图像是微不足道的。我对其他两个步骤的难度如此之大感到震惊。

所附图片显示了我想要实现的目标。有人会好心地握住我的手吗?到目前为止,我发现的每个代码示例似乎都会破坏图像、上下颠倒、看起来像废话、绘制越界或无法正常工作。

【问题讨论】:

  • 您的图片的链接已损坏。
  • 如果我们感到震惊的是,为什么 Apple 没有将它添加到 UIImagePickerController - 它太难了 ;-)

标签: iphone ios image-processing core-graphics


【解决方案1】:

我发现 Evgenii Kanvets 发布的 Swift 3 并没有统一缩放图像。

这是我的 Swift 4 版本的不挤压图像的函数:

static func resizedCroppedImage(image: UIImage, newSize:CGSize) -> UIImage? {

    // This function returns a newImage, based on image
    // - image is scaled uniformaly to fit into a rect of size newSize
    // - if the newSize rect is of a different aspect ratio from the source image
    //     the new image is cropped to be in the center of the source image
    //     (the excess source image is removed)

    var ratio: CGFloat = 0
    var delta: CGFloat = 0
    var drawRect = CGRect()

    if newSize.width > newSize.height {

        ratio = newSize.width / image.size.width
        delta = (ratio * image.size.height) - newSize.height
        drawRect = CGRect(x: 0, y: -delta / 2, width: newSize.width, height: newSize.height + delta)

    } else {

        ratio = newSize.height / image.size.height
        delta = (ratio * image.size.width) - newSize.width
        drawRect = CGRect(x: -delta / 2, y: 0, width: newSize.width + delta, height: newSize.height)

    }

    UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
    image.draw(in: drawRect)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
} 

【讨论】:

  • 我必须在UIGraphicsBeginImageContextWithOptions 中将缩放比例设置为 1.0,但其他的效果很好。谢谢!
【解决方案2】:

这是由 William T 发布的 Sam Wirch's guide to swift 的 Swift 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
    }

}

【讨论】:

    【解决方案3】:

    这是 Jane Sales 在 Swift 中的答案的一个版本。干杯!

    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
    }
    

    【讨论】:

      【解决方案4】:

      Swift 版本:

          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
      }
      

      【讨论】:

      • 不错的小功能,但我很确定这只是将图像拉伸到特定尺寸,不会保持纵横比和裁剪......
      • 是的,你没看错,这仅用于将图像拉伸到特定尺寸。
      【解决方案5】:

      我转换了Sam Wirch's guide to swift,它对我来说效果很好,尽管最终图像中有一些我无法解决的非常轻微的“挤压”。

      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
      }
      

      如果有人想要客观的 c 版本,在他的网站上。

      【讨论】:

        【解决方案6】:

        这个问题似乎已经解决了,但是在我寻求一个我可以更容易理解(并用 Swift 编写)的解决方案时,我想到了这个(也发布到:How to crop the UIImage?


        我希望能够根据纵横比从区域裁剪,并根据外部边界范围缩放到大小。这是我的变体:

        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
            }
        }
        

        有几件事让我感到困惑,裁剪和调整大小的不同问题。裁剪由您传递给 drawInRect 的矩形的原点处理,缩放由大小部分处理。就我而言,我需要将源上的裁剪矩形的大小与相同纵横比的输出矩形相关联。然后输出/输入比例因子,这需要应用于drawRect(传递给drawInRect)。

        需要注意的是,这种方法有效地假设您正在绘制的图像大于图像上下文。我没有对此进行测试,但我认为您可以使用此代码来处理裁剪/缩放,但将比例参数明确定义为上述比例参数。默认情况下,UIKit 根据屏幕分辨率应用乘数。

        最后,应该注意的是,这种 UIKit 方法比 CoreGraphics / Quartz 和 Core Image 方法级别更高,并且似乎可以处理图像方向问题。还值得一提的是,它非常快,仅次于 ImageIO,根据这里的这篇文章:http://nshipster.com/image-resizing/

        【讨论】:

          【解决方案7】:
          - (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];
          

          【讨论】:

            【解决方案8】:

            accepted answer on how to resize and then crop UIImage (Aspect Fill) 的 Xamarin.iOS 版本是 下面

                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;
                }
            

            【讨论】:

              【解决方案9】:

              较早的帖子包含调整 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;
              }
              

              就裁剪而言,我相信如果您更改方法以使用与上下文不同的大小进行缩放,则生成的图像应该被裁剪到上下文的范围内。

              【讨论】:

              • 对为什么这会修复图像方向毫无意义,但它确实解决了我的问题,即相机在originalImage 中没有返回正确的方向。谢谢。
              • 我发现在 Retina 设备上调整图像大小看起来很模糊。为了保持清晰,我将第一行修改为:UIGraphicsBeginImageContextWithOptions(newSize, 1.0f, 0.0f);。 (此处解释:stackoverflow.com/questions/4334233/…
              • 它会旋转图像 - 但不能正确裁剪!为什么它有这么多票?
              【解决方案10】:

              给你。这个是完美的;-)

              编辑:见下面的评论 - “不适用于某些图像,失败:CGContextSetInterpolationQuality: invalid context 0x0 error”

              // 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;
              }
              

              【讨论】:

              • 看起来真的很漂亮 :) 我喜欢这里的 InterpolationQuality
              • 不适用于某些图像,失败并出现:CGContextSetInterpolationQuality: invalid context 0x0 error
              【解决方案11】:
              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);
              

              【讨论】:

                【解决方案12】:

                我需要同样的东西 - 在我的例子中,选择适合缩放后的尺寸,然后裁剪每一端以适应其余部分的宽度。 (我在横向工作,所以可能没有注意到纵向模式的任何缺陷。)这是我的代码 - 它是 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;
                }
                

                【讨论】:

                • 奇怪的是它在模拟器中工作但在设备上我收到了 ExecBadAccess..
                • 错误执行的问题出现了,因为 UIImage 函数不是线程安全的。这就是为什么它有时会崩溃,有时不会
                • 这段代码对我来说效果很好,但在视网膜上却很模糊。将此代码与下面的注释相结合使一切变得完美:stackoverflow.com/questions/603907/…
                • 使用 UIGraphicsBeginImageContextWithOptions(targetSize, YES, 0.0);使视网膜上的图像也很好。
                • 这适用于纵向模式,但不适用于横向模式。高度在景观中被拉伸。知道为什么吗?
                【解决方案13】:

                以下简单代码对我有用。

                [imageView setContentMode:UIViewContentModeScaleAspectFill];
                [imageView setClipsToBounds:YES];
                

                【讨论】:

                • 您的代码确实适用于 UIImageView 对象。然而,这个问题是关于缩放UIImage 对象本身。
                【解决方案14】:

                我修改了 Brad Larson 的代码。它将在给定的矩形中填充图像。

                -(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;
                }
                

                【讨论】:

                • 用另外两张图片进行测试,纵向和横向。这不是执行纵横比填充。
                【解决方案15】:
                + (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;
                }
                

                我建议这个。她不是美女吗? ;)

                【讨论】:

                • 这个很好,如果您删除第一个 if 语句,它将充当 AspectFill。
                【解决方案16】:

                有一段很棒的代码与调整图像大小和其他几个操作有关。当我试图弄清楚如何调整图像大小时,我遇到了这个问题...... http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

                【讨论】:

                  猜你喜欢
                  • 2013-10-22
                  • 1970-01-01
                  • 2014-01-11
                  • 2015-12-04
                  • 2017-02-06
                  • 1970-01-01
                  • 2013-03-01
                  相关资源
                  最近更新 更多