How do I create and apply the image skew transform that I have calculated?
I already asked this question and Kenny gave me a good answer (many thanks to him), but I still in confusion about the final realization. So, the question is - how to get access to the matrix of the certain pixel in the image.
I translated Kenny's sample to the Objective-C:
- (NSArray *) compute_transform_matrix:(float)X
Y:(float)Y
W:(float)W
H:(float)H
x1a:(float)x1a
y1a:(float)y1a
x2a:(float)x2a
y2a:(float)y2a
x3a:(float)x3a
y3a:(float)y3a
x4a:(float)x4a
y4a:(float)y4a {
float y21 = y2a - y1a, y32 = y3a - y2a, y43 = y4a - y3a, y14 = y1a - y4a, y31 = y3a - y1a, y42 = y4a - y2a;
float a = -H*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42);
float b = W*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);
float c = H*X*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42) - H*W*x1a*(x4a*y32 - x3a*y42 + x2a*y43) - W*Y*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);
float d = H*(-x4a*y21*y3a + x2a*y1a*y43 - x1a*y2a*y43 - x3a*y1a*y4a + x3a*y2a*y4a);
float e = W*(x4a*y2a*y31 - x3a*y1a*y42 - x2a*y31*y4a + x1a*y3a*y42);
float f = -(W*(x4a*(Y*y2a*y31 + H*y1a*y32) - x3a*(H + Y)*y1a*y42 + H*x2a*y1a*y43 + x2a*Y*(y1a - y3a)*y4a + x1a*Y*y3a*(-y2a + y4a)) - H*X*(x4a*y21*y3a - x2a*y1a*y43 + x3a*(y1a - y2a)*y4a + x1a*y2a*(-y3a + y4a)));
float g = H*(x3a*y21 - x4a*y21 + (-x1a + x2a)*y43);
float h = W*(-x2a*y31 + x4a*y31 + (x1a - x3a)*y42);
float i = W*Y*(x2a*y31 - x4a*y31 - x1a*y42 + x3a*y42) + H*(X*(-(x3a*y21) + x4a*y21 + x1a*y43 - x2a*y43) + W*(-(x3a*y2a) + x4a*y2a + x2a*y3a - x4a*y3a - x2a*y4a + x3a*y4a));
return [NSArray arrayWithObjects:
[NSArray arrayWithObjects:
[NSNumber numberWithFloat:a],[NSNumber numberWithFloat:b],[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:c],nil],
[NSArray arrayWithObjects:
[NSNumber numberWithFloat:d],[NSNumber numberWithFloat:e],[NSNumber numberWithFloat:0],[NSNumber numberWithFlo开发者_运维知识库at:f],nil],
[NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],[NSNumber numberWithFloat:0],nil],
[NSArray arrayWithObjects:
[NSNumber numberWithFloat:g],[NSNumber numberWithFloat:h],[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:i],nil],
nil];
}
And, at the very beginning I create the image bitmap - "imageBitmap":
- (void) createImageBitmap{
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"Demo.png" ofType:nil];
UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
CGImageRef image = CGImageRetain(img.CGImage);
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef imageBitmap = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(imageBitmap, CGRectMake(0, 0, width, height), image);
}
Then, I suppose, I need to do following:
for(int x=0;x<width;x++){
for(int y=0;x<height;y++){
NSArray* matrixForPoint = [self compute_transform_matrix:x Y:y W:width H:height x1a:0 y1a:0 x2a:width y2a:0 x3a:width y3a:height x4a:0 y4a:height];
// set Matrix for x, y point to "imageBitmap" bitmap, but HOW?????????
}
}
So, how to set Matrix for x, y point to "imageBitmap" bitmap?
Many thanks in advance
Kenny's solution provides you with a means of generating a CATransform3D which you would then apply to the CALayer or UIView's layer that is hosting the image. You need to assign the matrix elements for that transform with the values you have calculated here. My recommendation would be to have your -compute_transform_matrix:
method return a CATransform3D, and replace the last few lines with
CATransform3D skewTransform;
skewTransform.m11 = a;
skewTransform.m12 = b;
skewTransform.m13 = 0;
skewTransform.m14 = c;
skewTransform.m21 = d;
skewTransform.m22 = e;
skewTransform.m23 = 0;
skewTransform.m24 = f;
skewTransform.m31 = 0;
skewTransform.m32 = 0;
skewTransform.m33 = 1;
skewTransform.m34 = 0;
skewTransform.m41 = g;
skewTransform.m42 = h;
skewTransform.m43 = 0;
skewTransform.m44 = i;
return skewTransform;
You can then set this transform on your layer or view's layer to achieve this skew effect.
精彩评论