3

画面上の図形に任意の色を付ける必要があります。私は現在、自分の欲望に合わせて色を変更したい UIImage でこれを行おうとしています。私の知る限り、これを行う唯一の方法は、UIImage の個々のピクセルを取得することです。これには、この問題を修正するためにさらに多くのコード行を記述したいと考えています。私が書いたもの以外に UIImage の色を変更する方法はありますか? 状況に応じて図形を描画して塗りつぶす方が簡単でしょうか?

TY.

更新: Hexagon は正しい方向に描画されていますが、まったく正しく塗りつぶされません。コードは次のとおりです。

self.Hexagon.lineWidth=10;
[self.Hexagon moveToPoint:CGPointMake(hexWidth/2, 0)];
[self.Hexagon addLineToPoint:CGPointMake(hexWidth, hexHeight/4)];
[self.Hexagon addLineToPoint:CGPointMake(hexWidth, hexHeight*0.75)];
[self.Hexagon addLineToPoint:CGPointMake(hexWidth/2, hexHeight)];
[self.Hexagon addLineToPoint:CGPointMake(0, hexHeight*0.75)];
[self.Hexagon addLineToPoint:CGPointMake(0, hexHeight/4)];
[self.Hexagon addLineToPoint:CGPointMake(hexWidth/2, 0)];

[self.Hexagon closePath];
[[UIColor blackColor] setStroke];
[self.Hexagon stroke];

[[UIColor whiteColor] setFill];
[self.Hexagon fill];
4

3 に答える 3

4

を使用することをお勧めしCAShapeLayerます。塗りつぶしの色をアニメーション化することもできます。パフォーマンスが非常に良くなり、メモリ使用量が少なくなります。

この関数は、六角形を含む CGPath を作成します: (OP の質問に基づく)

CGPathRef CGPathCreateHexagon( CGFloat hexWidth, CGFloat hexHeight )
{
    CGMutablePathRef p = CGPathCreateMutable() ;
    CGPathMoveToPoint( p, NULL,  hexWidth * 0.5, 0.0 ) ;
    CGPathAddLineToPoint( p, NULL,  hexWidth, hexHeight * 0.75 ) ;
    CGPathAddLineToPoint( p, NULL, hexWidth, hexHeight * 0.75 ) ;
    CGPathAddLineToPoint( p, NULL, hexWidth * 0.5, hexHeight ) ;
    CGPathAddLineToPoint( p, NULL, 0.0, hexHeight * 0.75 ) ;
    CGPathAddLineToPoint( p, NULL, hexWidth * 0.5, 0.0 ) ;
    CGPathAddLineToPoint( p, NULL, 0.0, hexHeight * 0.25 ) ;
    CGPathAddLineToPoint( p, NULL, hexWidth * 0.5, 0.0 ) ;
    CGPathCloseSubpath( p ) ;

    return p ;
}

を設定するときに使用する方法UIView:

-(void)addHexagonLayer
{        
    CAShapeLayer * layer = [ CAShapeLayer layer ] ;
    layer.lineWidth = 10.0 ;
    {
        CGPathRef p = CGPathCreateHexagon( 100.0, 100.0 ) ;
        layer.path = p ;
        CGPathRelease( p ) ;
    }       
    layer.fillColor = [[ UIColor redColor ] CGColor ] ; // put your fill color here

    layer.position = (CGPoint){ CGRectGetMidX( self.view.bounds ), CGRectGetMidY( self.view.bounds ) } ; // position your hexagon layer appropriately.
    [ self.view.layer addSublayer:layer ] ; // add layer to your view and position appropriately        

}

編集楽しみのために完全なデモを作成しました。

#import "AppDelegate.h"

static CGPathRef CGPathCreateHexagon( CGAffineTransform * t, CGFloat w, CGFloat h )
{
    CGFloat w_4 = w * 0.25 ;
    CGFloat w_2 = w * 0.5f ;
    CGFloat h_2 = h * 0.5f ;

    CGMutablePathRef p = CGPathCreateMutable() ;
    CGPathAddLines( p, t, (CGPoint[]){
        { -w_4, h_2 }, { w_4, h_2 }, { w_2, 0 }, { w_4, -h_2 }, { -w_4, -h_2 }, { -w_2, 0 }
    }, 6 ) ;
    CGPathCloseSubpath( p ) ;

    return p ;
}

@implementation CALayer (SetPositionPixelAligned)

-(CGPoint)pixelAlignedPositionForPoint:(CGPoint)p
{
    CGSize size = self.bounds.size ;
    CGPoint anchorPoint = self.anchorPoint ;

    CGPoint result = (CGPoint){ roundf( p.x ) + anchorPoint.x * fmodf( size.width, 2.0f ), roundf( p.y ) + anchorPoint.y * fmodf( size.height, 2.0f ) } ;
    return result;
}

@end

@interface HexagonsView : UIView
@property ( nonatomic ) CGFloat hexHeight ;
@property ( nonatomic ) CGFloat hexWidth ;
@property ( nonatomic, readonly ) CGPathRef hexagonPath ;
@end

@implementation HexagonsView
@synthesize hexagonPath = _hexagonPath ;

-(void)dealloc
{
    CGPathRelease( _hexagonPath ) ;
    _hexagonPath = NULL ;
}

-(CGPathRef)hexagonPath
{
    if ( !_hexagonPath )
    {
        _hexagonPath = CGPathCreateHexagon( NULL, self.hexWidth, self.hexHeight ) ;
    }

    return _hexagonPath ;
}

-(void)setHexWidth:(CGFloat)w
{
    _hexWidth = w ;
    CGPathRelease( _hexagonPath ) ;
    _hexagonPath = NULL ;
}

-(void)setHexHeight:(CGFloat)h
{
    _hexHeight = h ;
    CGPathRelease( _hexagonPath ) ;
    _hexagonPath = NULL ;
}

-(void)layoutSubviews
{
    [ super layoutSubviews ] ;
    CGRect bounds = self.bounds ;
    bounds.size.height += self.hexHeight * 0.5 ;    // make sure we cover last row ;

    CGPoint p ;
    p.x = CGRectGetMinY( bounds ) ;

    while( p.y < CGRectGetMaxY( bounds ) )
    {
        p.x = CGRectGetMinX( bounds ) ;
        while( p.x < CGRectGetMaxX( bounds ) )
        {
            {
                CAShapeLayer * layer = [ CAShapeLayer layer ] ;
                layer.path = self.hexagonPath ;
                layer.fillColor = [[ UIColor colorWithHue:(CGFloat)arc4random_uniform( 100 ) / 256.0  saturation:1.0 brightness:1.0 alpha:1.0 ] CGColor ]  ;
                layer.position = [ layer pixelAlignedPositionForPoint:p ] ;
                [ self.layer addSublayer:layer ] ;
            }

            CGPoint p2 = { p.x + self.hexWidth * 0.75f, p.y + self.hexHeight * 0.5f } ;

            if ( p2.y < CGRectGetMaxY( bounds ))    // no unnecessary hexagons
            {
                CAShapeLayer * layer = [ CAShapeLayer layer ] ;
                layer.path = self.hexagonPath ;
                layer.fillColor = [[ UIColor colorWithHue:(CGFloat)arc4random_uniform( 256 ) / 256.0  saturation:1.0 brightness:1.0 alpha:1.0 ] CGColor ]  ;
                layer.position = [ layer pixelAlignedPositionForPoint:p2 ] ;
                [ self.layer addSublayer:layer ] ;
            }

            p.x += self.hexWidth * 1.5 ;
        }
        p.y += self.hexHeight ;
    }
}

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];

    HexagonsView * view = [[ HexagonsView alloc ] initWithFrame:self.window.bounds ] ;
    view.hexHeight = 100.0f ;
    view.hexWidth = 100.0f ;

    [ self.window addSubview:view ] ;

    [self.window makeKeyAndVisible];
    return YES;
}

@end
于 2013-07-03T00:53:20.783 に答える
1

UIView をサブクラス化し、次のコードを追加します。

- (void)drawRect:(CGRect)rect
{ 

        CGContextRef context = UIGraphicsGetCurrentContext(); 

//Set color of the border
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
//Set color of the fill
        CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);

        // Set width of border line
        CGContextSetLineWidth(context, 2.0);

//Pseudocode: Draw your hexagons with something like this
        for(int idx = 0; idx < self.points.count; idx++)
        {

            point = [self.points objectAtIndex:idx];//Edited 
            if(idx == 0)
            {
                // move to the first point
                CGContextMoveToPoint(context, point.x, point.y);
            }
            else
            {
//Add a point to the hexagon. The last point should be equal to the first point
                CGContextAddLineToPoint(context, point.x, point.y);
            }
        }
//Fill in the hexagon
        CGContextDrawPath(context, kCGPathFillStroke)
}

描画する六角形ごとにこれを繰り返します。理想的には、簡単に参照できるように、六角形のすべてのポイントを配列に配置します。

于 2013-07-02T01:35:26.147 に答える
1

形状を記述する UIBezierPath を作成し、その fill メソッドを使用して希望の色を描画します。

于 2013-07-02T00:48:24.077 に答える