1

我正在开发摄影应用程序。在那我需要为NSImage我使用这样的绘图创建框架

NSImage *fg_img = [[NSImage alloc]initWithData:[NSData dataWithContentsOfFile:filepath]];
        //NSData *imageData1 = [NSData dataWithContentsOfURL: [NSURL encryptedFileURLWithPath:str]] ;
        NSImage *bg_img = [[NSImage alloc]initWithContentsOfURL:[NSURL encryptedFileURLWithPath:str]];



    NSImage *newImage ;

    NSRect imageRect = NSMakeRect(0,0, fg_img.size.width+fg_img.size.width/5, fg_img.size.height+fg_img.size.height/5);
    newImage = [[NSImage alloc] initWithSize: NSMakeSize(imageRect.size.width,imageRect.size.height)];
    NSRect fgrect = NSMakeRect(imageRect.size.width*0.03,imageRect.size.height*0.04, imageRect.size.width-imageRect.size.width/15.5, imageRect.size.height-imageRect.size.height/12);

    [newImage lockFocus];

    [fg_img drawInRect:fgrect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    [bg_img drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

    [newImage unlockFocus];

但不清楚..

原始帧图像

我原来的框架是

当我缩放它的输出是 在此处输入图像描述

在上图中,当我调整框架图像的大小时,框架的宽度发生了变化。我需要在缩放时不改变帧图像的宽度。

更新:

但是你的代码显示是这样的

预习

如果我给大图,基本图像会变得很薄

4

3 回答 3

3

我认为您正在寻找九部分图像。九部分图像仅垂直调整左侧和右侧,仅水平调整顶部和底部,中心是独立调整轴的大小,角不调整大小。

_____________ 
|c |  hor | c|  
|__|______|__|
|  |      |  |
|v | axes |v |
|e |indep.|e |
|r |      |r |
|__|______|__|
|c |  hor |c |
|__|______|__|

苹果有一个方法可以帮助你绘制这样的图像:NSDrawNinePartImage 这里 但它需要准备图像。

初始化代码是这样的:

    static NSImage *baseImage = NULL;
    static NSImage *topLeftCornerImage;
    static NSImage *topEdgeImage;
    static NSImage *topRightCornerImage;
    static NSImage *leftEdgeImage;
    static NSImage *centerImage;
    static NSImage *rightEdgeImage;
    static NSImage *bottomLeftCornerImage;
    static NSImage *bottomEdgeImage;
    static NSImage *bottomRightCornerImage;

    + (void)initialize;
    {
        if (baseImage) return;

        //46x46


        baseImage = [NSImage imageNamed:@"badge.png"];

        topLeftCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
        [topLeftCornerImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,22)
                     fromRect:NSMakeRect(0.0,24,22,22)
                    operation:NSCompositeCopy fraction:1.0];
        [topLeftCornerImage unlockFocus];

        topEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 22)];
        [topEdgeImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,2,22)
                     fromRect:NSMakeRect(22,24,2,22)
                    operation:NSCompositeCopy fraction:1.0];
        [topEdgeImage unlockFocus];

        topRightCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
        [topRightCornerImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,22)
                     fromRect:NSMakeRect(24,24,22,22)
                    operation:NSCompositeCopy fraction:1.0];
        [topRightCornerImage unlockFocus];

        leftEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 2)];
        [leftEdgeImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,2)
                     fromRect:NSMakeRect(0,22,22,2)
                    operation:NSCompositeCopy fraction:1.0];
        [leftEdgeImage unlockFocus];

        centerImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 2)];
        [centerImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,2,2)
                     fromRect:NSMakeRect(22,22,2,2)
                    operation:NSCompositeCopy fraction:1.0];
        [centerImage unlockFocus];

        rightEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 2)];
        [rightEdgeImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,2)
                     fromRect:NSMakeRect(24,24,22,2)
                    operation:NSCompositeCopy fraction:1.0];
        [rightEdgeImage unlockFocus];

        bottomLeftCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
        [bottomLeftCornerImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,22)
                     fromRect:NSMakeRect(0,0,22,22)
                    operation:NSCompositeCopy fraction:1.0];
        [bottomLeftCornerImage unlockFocus];

        bottomEdgeImage = [[NSImage alloc] initWithSize:NSMakeSize(2, 22)];
        [bottomEdgeImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0, 0, 2, 22)
                     fromRect:NSMakeRect(22, 0, 2, 22)
                    operation:NSCompositeCopy fraction:1.0];
        [bottomEdgeImage unlockFocus];

        bottomRightCornerImage = [[NSImage alloc] initWithSize:NSMakeSize(22, 22)];
        [bottomRightCornerImage lockFocus];
        [baseImage drawInRect:NSMakeRect(0,0,22,22)
                     fromRect:NSMakeRect(24,0,22,22)
                    operation:NSCompositeCopy fraction:1.0];
        [bottomRightCornerImage unlockFocus];
    }

绘图代码:

NSDrawNinePartImage([self bounds],
                    topLeftCornerImage, topEdgeImage, topRightCornerImage,
                    leftEdgeImage, centerImage, rightEdgeImage,
                    bottomLeftCornerImage, bottomEdgeImage, bottomRightCornerImage,
                    NSCompositeSourceOver, 1.0, NO);

这是我实现基于 CALayer 的九部分图像的另一个示例 - NinePartLayer。

NinePartLayer.h

#import <Foundation/Foundation.h>


@interface NinePartLayer : CALayer {
@private
    NSSize _blockSize;
    NSMutableArray* layers;
    NSMutableArray* _images;
}

+ (NinePartLayer*) layerWithImage:(NSImage*)aImage;

@property (assign)NSSize blockSize;
- (void) setImage:(NSImage*)aImage;
@end

NinePartLayer.m

#import "NinePartLayer.h"

@interface NinePartLayer()

@property (retain)NSMutableArray* layers;
@property (retain)NSMutableArray* images;

@end

@implementation NinePartLayer
@synthesize images = _images;
@synthesize blockSize = _blockSize;
@synthesize layers;

+(NSImage*) imageFromImage:(NSImage *)anImage rect:(NSRect)aRect
{
    @try {
        NSPoint point = { -aRect.origin.x, -aRect.origin.y };
        NSImage *theImage = [[self alloc] initWithSize:aRect.size];
        [theImage lockFocus];
        [anImage compositeToPoint:point operation:NSCompositeCopy];
        [theImage unlockFocus];
        [theImage autorelease];
        return theImage;
    }
    @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);
        return nil;
    }
}

+ (NinePartLayer*) layerWithImage:(NSImage*)aImage
{
    NinePartLayer* newLayer = [NinePartLayer layer];
    [newLayer setImage:aImage];
    return newLayer;
}

- (id)init {
    self = [super init];
    if (self) {
        self.layers = [NSMutableArray array];
        self.images = [NSMutableArray array];
    }
    return self;
}

- (void) updateLayers
{
    for (int i = 0; i < 3 && i < [self.images count]; ++i) {
        NSMutableArray* row = [self.images objectAtIndex:i];
        for (int j = 0; j < 3 && j < [row count]; ++j) {
            CALayer* item = [row objectAtIndex:j];
            float x,y,width,height;
            if(i == 0){
                y = 0;
                height = floorf(self.blockSize.height);
            } else if(i == 1){
                y = ceilf(self.blockSize.height);      
                height = self.frame.size.height - 2*self.blockSize.height;
            } else if(i == 2){
                y = self.frame.size.height - self.blockSize.height;
                height = self.blockSize.height;
            };
            if(j == 0){
                x = 0;
                width = self.blockSize.width;
            } else if(j == 1){
                x = self.blockSize.width;
                width = self.frame.size.width - 2*self.blockSize.width;
            } else if(j == 2){
                x = self.frame.size.width - self.blockSize.width;
                width = self.blockSize.width;
            };

            item.frame = CGRectMake(x, y, width, height);

            float delta=0;

            if((i==1)&&(j==0))
            {
                item.frame = CGRectMake(x, y-delta, width+delta, height+2*delta);
            }

            if((i==2)&&(j==1))
            {
                item.frame = CGRectMake(x-delta, y-delta, width+2*delta, height+delta);
            }

            if((i==1)&&(j==2))
            {
                item.frame = CGRectMake(x-delta, y-delta, width+delta, height+2*delta);
            }

            if((i==0)&&(j==1))
            {
                item.frame = CGRectMake(x-delta, y, width+2*delta, height+delta);
            }
        }
    } 
}

- (void) setImage:(NSImage*)aImage
{
   for(int i = 0; i < [self.layers count]; ++i)
        [[self.layers objectAtIndex:i] removeFromSuperlayer];

    [self.layers removeAllObjects];

    self.images = [NSMutableArray array];
    self.layers = [NSMutableArray array];
    if(!aImage)
        return;

    for (int i = 0; i < 3; ++i) {
        NSMutableArray* row = [NSMutableArray array];
        for (int j = 0; j < 3; ++j) {
            NSImage* img = [NSImage imageFromImage:aImage 
                                              rect:NSMakeRect((float)j/3.0*[aImage size].width, 
                                                              (float)i/3.0*[aImage size].height, 
                                                              1.0/3.0*[aImage size].width,
                                                              1.0/3.0*[aImage size].height)];
            self.blockSize = NSMakeSize(1.0/3.0*[aImage size].width, 1.0/3.0*[aImage size].height);

            CALayer* item = [CALayer layer];
            [item performSelectorOnMainThread:@selector(setContents:) withObject:img waitUntilDone:NO];
            [item performSelectorOnMainThread:@selector(setContentsGravity:) withObject:kCAGravityResize waitUntilDone:NO];
            [self performSelectorOnMainThread:@selector(addSublayer:) withObject:item waitUntilDone:NO];
            [row addObject:item];
            [self.layers addObject:item];
        }
        [self.images addObject:row];
    }
    [self performSelectorOnMainThread:@selector(updateLayers) withObject:nil waitUntilDone:NO];
}

- (void) setFrame:(CGRect)frame
{
    [super setFrame:frame];
    [self updateLayers];
}

- (void) setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
    [self updateLayers];
}

- (void) setPosition:(CGPoint)position
{
    [super setPosition:position];
    [self updateLayers];
}

- (void)dealloc {
    self.layers = nil;
    self.images = nil;
    [super dealloc];
}
@end

用法:

    NinePartLayer * pageContainerShadowlayer=[NinePartLayer layerWithImage:[NSImage imageNamed:@"drop_shadow.png"]];
    pageContainerShadowlayer.frame=[mainView layer].bounds;
    pageContainerShadowlayer.autoresizingMask=kCALayerWidthSizable | kCALayerHeightSizable;
    [[rootView layer] insertSublayer:pageContainerShadowlayer atIndex:3];
于 2013-02-01T16:32:45.083 回答
1

万一其他人在几年后偶然发现了这个问题(就像我一样)——从 macOS 10.10 (Yosemite) 开始,NSImage 有一个capInsets属性可以使用单个源图像处理九部分图像行为。耶!

于 2021-08-09T08:00:59.263 回答
0

你考虑过 NSDrawNinePartImage吗?这是一个专门为在您建议的排列中绘制九个图像(四个角、四个边缘和一个中心)而设计的功能,没有可见的接缝,也不会拉伸角和边缘图像。

于 2013-02-03T17:20:19.223 回答