Gradientowa tekstura ma niewłaściwą skalę na Retina Mac
Napisałem funkcję generowania gradientu jako kategorię na SKTexture. Działa dobrze na 1x ekranach, ale siatkówka sprawia, że tekstura jest zbyt duża, podwójna szerokość i podwójna wysokość, czyli niewłaściwa skala. Próbowałem to zrobić, zmieniając piksele i punkty, ale nie mogę tego zrobić poprawnie. Czy ktoś może mi pomóc?
+(SKTexture*)gradientWithSize:(const CGSize)SIZE colors:(NSArray*)colors {
// Hopefully this function would be platform independent one day.
// Correct way to find scale?
DLog(@"backingScaleFactor: %f", [[NSScreen mainScreen] backingScaleFactor]);
const CGFloat SCALE = [[NSScreen mainScreen] backingScaleFactor];
//const size_t WIDTH_PIXELS = SIZE.width * SCALE;
//const size_t HEIGHT_PIXELS = SIZE.height * SCALE;
CGContextRef cgcontextref = MyCreateBitmapContext(SIZE.width, SIZE.height, SCALE);
NSAssert(cgcontextref != NULL, @"Failed creating context!");
// CGBitmapContextCreate(
// NULL, // let the OS handle the memory
// WIDTH_PIXELS,
// HEIGHT_PIXELS,
CAGradientLayer* gradient = CAGradientLayer.layer;
//gradient.contentsScale = SCALE;
gradient.frame = CGRectMake(0, 0, SIZE.width, SIZE.height);
NSMutableArray* convertedcolors = [NSMutableArray array];
for (SKColor* skcolor in colors) {
[convertedcolors addObject:(id)skcolor.CGColor];
}
gradient.colors = convertedcolors;
[gradient renderInContext:cgcontextref];
CGImageRef imageref = CGBitmapContextCreateImage(cgcontextref);
DLog(@"imageref pixel size: %zu %zu", CGImageGetWidth(imageref), CGImageGetHeight(imageref));
SKTexture* texture1 = [SKTexture textureWithCGImage:imageref];
DLog(@"size of gradient texture: %@", NSStringFromSize(texture1.size));
CGImageRelease(imageref);
CGContextRelease(cgcontextref);
return texture1;
}
CGContextRef MyCreateBitmapContext(const size_t POINTS_W, const size_t POINTS_H, const CGFloat SCALE) {
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
//int bitmapByteCount;
size_t bitmapBytesPerRow;
const size_t PIXELS_W = POINTS_W * SCALE;
const size_t PIXELS_H = POINTS_H * SCALE;
bitmapBytesPerRow = (PIXELS_W * 4);// 1
//bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2
bitmapData = NULL;
#define kBitmapInfo kCGImageAlphaPremultipliedLast
//#define kBitmapInfo kCGImageAlphaPremultipliedFirst
//#define kBitmapInfo kCGImageAlphaNoneSkipFirst
// According to http://stackoverflow.com/a/18921840/129202 it should be safe to just cast
CGBitmapInfo bitmapinfo = (CGBitmapInfo)kBitmapInfo; //kCGImageAlphaNoneSkipFirst; //0; //kCGBitmapAlphaInfoMask; //kCGImageAlphaNone; //kCGImageAlphaNoneSkipFirst;
context = CGBitmapContextCreate (bitmapData,// 4
PIXELS_W,
PIXELS_H,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
bitmapinfo
);
if (context == NULL) {
free (bitmapData);// 5
fprintf (stderr, "Context not created!");
return NULL;
}
CGColorSpaceRelease( colorSpace );// 6
// TEST!!
// CGContextClipToRect(context, CGRectMake(0, 0, POINTS_W, POINTS_H));
CGContextClipToRect(context, CGRectMake(0, 0, PIXELS_W, PIXELS_H));
CGContextScaleCTM(context, SCALE, SCALE);
return context;// 7
}
Więc dla niektórych podsumuj, oczekuję zadzwonić+(SKTexture*)gradientWithSize:(const CGSize)SIZE colors:(NSArray*)colors
używanie punktów dla SIZE.