критическое ...
, если вы делаете обычную вещь, например, рисуя размытую версию изображения над собой.
Вы почтиконечно, нужен код, подобный этому ...
float isf;
isf = [[UIScreen mainScreen] bounds].size.width / wholeImageWidth;
(это если вы рисуете полноэкранный режим; настраивайте очевидным образом, если рисуете в окне), где wholeImageWidth - реальная ширина редактируемого изображения.
затем, когда вы создаете шаблон обводки, вы используете его, как этот
CGAffineTransformScale( CGAffineTransformIdentity, isf, -isf)
, но, к сожалению, вам, возможно, придется пересобирать его по-разному для камеры и альбома.Так что-то вроде .......
if ( self.wasFromCameraNotAlbum )
{
strokePattern = CGPatternCreate(
NULL,
CGRectMake(0,0,wholeWidth,wholeHeight),
CGAffineTransformConcat(
CGAffineTransformScale( CGAffineTransformIdentity, isf, -isf),
CGAffineTransformRotate( CGAffineTransformIdentity, 90*M_PI/180 )
),
wholeWidth,wholeHeight,
kCGPatternTilingNoDistortion, true, &kPatternCallbacks);
}
else
{
strokePattern = CGPatternCreate(
NULL,
CGRectMake(0,0,wholeWidth,wholeHeight),
CGAffineTransformScale( CGAffineTransformIdentity, isf, -isf),
wholeWidth,wholeHeight,
kCGPatternTilingNoDistortion, true, &kPatternCallbacks);
}
Для поиска в Google это связано с камерой, вращением, iPhone 6+, iOS8, альбомом.
С llama591'sОтвет был таким потрясающим.Вот пример кода, который может когда-нибудь кому-нибудь помочь.Это простейший из возможных кодов , который я могу написать для рисования шаблонов:
Это прекрасно работает в Xcode5 / iOS7 (это январь 2014 г.):
Вот несколько очень типичных кодов для рисованияэто рисует СИНИЙ ЛИНИИ:
-(void)drawRect:(CGRect)rect
{
[curImage drawAtPoint:CGPointMake(0, 0)];
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context,
previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, 20.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextStrokePath(context);
[super drawRect:rect];
}
Обратите внимание на вызов CGContextSetStrokeColorWithColor , который просто устанавливает линию в сплошную линию, в данном случае синий.
Следующим здесь являетсяидентичный кодНо мы заменяем эту одну строку кода всем кодом для рисования шаблона .(И есть также новая отдельная подпрограмма обратного вызова, которая тривиальна.)
Для ясности здесь только 15 строк кода, которые заменят одну простую строку кода StrokeColor:
const CGPatternCallbacks kPatternCallbacks = {0, simplePatternCallback, NULL};
CGFloat color1[] = {1.0, 1.0, 1.0, 1.0};
CGPatternRef strokePattern = CGPatternCreate(
NULL,
CGRectMake(0,0,100,100),
CGAffineTransformIdentity,
100,100,
kCGPatternTilingNoDistortion,
true,
&kPatternCallbacks);
CGContextSetStrokeColorSpace(UIGraphicsGetCurrentContext(),
CGColorSpaceCreatePattern(NULL););
CGContextSetStrokePattern(context, strokePattern, color1);
CGPatternRelease(strokePattern);
strokePattern = NULL;
Шаблон должен быть PNG в вашем проекте, который может быть, скажем, 100x100 пикселей, здесь он называется «pattern100100.png».
Опять я заменил 1 строку кода на 15 строк кода дляшаблон.(А также есть отдельная тривиальная функция обратного вызова.) Вот и все:
-(void)drawRect:(CGRect)rect
{
[curImage drawAtPoint:CGPointMake(0, 0)];
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context,
previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, 20.0);
const CGPatternCallbacks kPatternCallbacks = {0, simplePatternCallback, NULL};
CGFloat color1[] = {1.0, 1.0, 1.0, 1.0};
CGPatternRef strokePattern = CGPatternCreate(
NULL,
CGRectMake(0,0,100,100),
CGAffineTransformIdentity,
100,100,
kCGPatternTilingNoDistortion,
true,
&kPatternCallbacks);
CGContextSetStrokeColorSpace(UIGraphicsGetCurrentContext(),
CGColorSpaceCreatePattern(NULL););
CGContextSetStrokePattern(context, strokePattern, color1);
CGPatternRelease(strokePattern);
strokePattern = NULL;
CGContextStrokePath(context);
[super drawRect:rect];
}
void simplePatternCallback(void *info, CGContextRef ctx)
{
UIImage *brushTexture = [UIImage imageNamed:@"pattern100100.png"];
CGContextDrawImage(ctx, CGRectMake(0, 0, 100,100), brushTexture.CGImage);
}
Несколько полезных комментариев для включения в код!
// re the final argument:
// from Apple doco: "If the specified pattern is a 'colored' pattern,
// pass an alpha value."
// in fact you have to pass in an array of four values.
// note, "stencil patterns" (aka "uncolored patterns") patterns
// are basically masks, rarely used
// re the "true" in CGPatternCreate, that means "coloured pattern"
// (ie not "stencil pattern")
Я действительно надеюсь, что это поможеткто-то.
ПРИМЕЧАНИЕ: всякий раз, когда вы видите подобные примеры кода (даже в Apple).Они всегда делают все это "внутри drawRect".Обратите внимание, что «strokePattern» действительно создается каждый раз, когда вызывается drawRect!Мне это кажется сумасшедшим, я всегда просто использую переменную или свойство для «strokePattern» и других элементов.Точно так же было бы смешно использовать imageNamed каждый раз при обратном вызове, просто использовать свойство, которое вы предварительно подготовили.
Опять же, я очень надеюсь, что это кому-то поможет.Приветствия
полезная сноска: в CGPaternCreate, пример кода показывает CGAffineTransformIdentity для аргумента три.
Часто вы используете какое-либо фото или другое динамическое изображение.В этом случае почти наверняка было бы ...
CGAffineTransformScale(CGAffineTransformIdentity,1,-1),
, чтобы позаботиться о перевернутом масштабе в основной графике.Надеюсь, это поможет.