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

9部構成の画像をお探しだと思います。9つの部分の画像は、左側と右側のみが垂直方向に、上下のみが水平方向にサイズ変更され、中央は軸のサイズが個別に変更され、コーナーはサイズ変更されません。

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

Appleには、そのような画像を描くのに役立つ方法があります。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];
    }

drawingCode:

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

これは、CALayerベースの9つの部分からなる画像(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、単一のソース画像を使用して9つの部分からなる画像の動作を処理するプロパティがあります。わーい!

于 2021-08-09T08:00:59.263 に答える
0

NSDrawNinePartImageを検討しましたか?これは、9つの画像(4つのコーナー、4つのエッジ、および中央)を、目に見える継ぎ目がなく、コーナーとエッジの画像を引き伸ばすことなく、提案した配置で描画するために特別に設計された機能です。

于 2013-02-03T17:20:19.223 に答える