代码之家  ›  专栏  ›  技术社区  ›  Marek H

如何水平移动图像以创建循环效果?

  •  0
  • Marek H  · 技术社区  · 7 年前

    如何水平移动图像,使移动的像素出现在另一侧,使其看起来像一个循环? 目前我正在使用drawInRect。有没有什么更好的方法可以做到这一点?

    looped world map

    - (CIImage *)image:(NSImage *)image shiftedBy:(CGFloat)shiftAmount
    {
    
        NSUInteger width = image.size.width;
        NSUInteger height = image.size.height;
        NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                      pixelsWide:width
                                                      pixelsHigh:height
                                                   bitsPerSample:8
                                                 samplesPerPixel:4
                                                        hasAlpha:YES
                                                        isPlanar:NO
                                                  colorSpaceName:NSDeviceRGBColorSpace
                                                     bytesPerRow:0
                                                    bitsPerPixel:0];
        [rep setSize:NSMakeSize(width, height)];
        [NSGraphicsContext saveGraphicsState];
        NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
        [NSGraphicsContext setCurrentContext:context];
    
    
        CGRect rect0 = CGRectMake(0, 0, width, height);
        CGRect leftSourceRect, rightSourceRect;
        CGRectDivide(rect0, &leftSourceRect, &rightSourceRect, shiftAmount, CGRectMinXEdge);
        CGRect rightDestinationRect = CGRectOffset(leftSourceRect, width - rightSourceRect.origin.x, 0);
        CGRect leftDestinationRect = rightSourceRect;
        leftDestinationRect.origin.x = 0;
    
        [image drawInRect:leftDestinationRect fromRect:rightSourceRect operation:NSCompositingOperationSourceOver fraction:1.0];
        [image drawInRect:rightDestinationRect fromRect:leftSourceRect operation:NSCompositingOperationSourceOver fraction:1.0];
    
        [NSGraphicsContext restoreGraphicsState];
        return [[CIImage alloc] initWithBitmapImageRep:rep];
    }
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   Marek H    7 年前

    我尝试使用CIFilter,但是性能下降了3-4倍。但是,代码更具可读性。

    - (CIImage *)image:(NSImage *)image shiftXBy:(CGFloat)shiftX YBy:(CGFloat)shiftY
    {
        //avoid calling TIFFRepresentation here cause the performance hit is even bigger
        CIImage *ciImage = [[CIImage alloc] initWithData:[image TIFFRepresentation]];
        CGAffineTransform xform = CGAffineTransformIdentity;
        NSValue *xformObj = [NSValue valueWithBytes:&xform objCType:@encode(CGAffineTransform)];
        ciImage = [ciImage imageByApplyingFilter:@"CIAffineTile"
                             withInputParameters:@{kCIInputTransformKey : xformObj} ];
        ciImage = [ciImage imageByCroppingToRect:CGRectMake(shiftX, shiftY, image.size.width, image.size.height)];
        return ciImage;
    }
    
        2
  •  0
  •   pointum    7 年前

    • 你的 NSView 子类应该具有 wantsLayer layerUsesCoreImageFilters 着手 true .
    • 将您的图像分配给 content 性质 NSView.layer (或添加新的子层)。
    • 创造 CIAffineTile

    现在,您可以更改过滤器的值,而无需重新加载或重画图像。这一切都将是硬件加速的。