だから私はいくつかのオリジナルの画像を持っています。
特定のマスクを使用して、この画像の一部を取得して表示する必要があります。マスクは長方形や形ではありません。さまざまなポリゴンと形状が含まれています。
それを実装する方法やチュートリアルはありますか?または、どこからこれを作り始めるのですか?小さなシェーダーを作成するか、画像の適切なピクセルなどを比較しますか?
アドバイスをいただければ幸いです。
ありがとうございました
だから私はいくつかのオリジナルの画像を持っています。
特定のマスクを使用して、この画像の一部を取得して表示する必要があります。マスクは長方形や形ではありません。さまざまなポリゴンと形状が含まれています。
それを実装する方法やチュートリアルはありますか?または、どこからこれを作り始めるのですか?小さなシェーダーを作成するか、画像の適切なピクセルなどを比較しますか?
アドバイスをいただければ幸いです。
ありがとうございました
画像をUIImageViewに配置し、その画像ビューに次のようなマスクを追加できます。
myImageView.layer.mask = myMaskLayer;
カスタムシェイプを描画するには、myMaskLayerは、drawInContext
メソッドを実装するCALayerの独自のサブクラスのインスタンスである必要があります。このメソッドは、画像に表示される領域を完全なアルファで描画し、非表示にする領域をゼロのアルファで描画する必要があります(必要に応じてアルファ間で使用することもできます)。これは、CALayerサブクラスの実装例であり、画像ビューでマスクとして使用すると、画像の左上隅にある楕円形の領域のみが表示されます。
@interface MyMaskLayer : CALayer
@end
@implementation MyMaskLayer
- (void)drawInContext:(CGContextRef)ctx {
static CGColorSpaceRef rgbColorSpace;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
rgbColorSpace = CGColorSpaceCreateDeviceRGB();
});
const CGRect selfBounds = self.bounds;
CGContextSetFillColorSpace(ctx, rgbColorSpace);
CGContextSetFillColor(ctx, (CGFloat[4]){0.0, 0.0, 0.0, 0.0});
CGContextFillRect(ctx, selfBounds);
CGContextSetFillColor(ctx, (CGFloat[4]){0.0, 0.0, 0.0, 1.0});
CGContextFillEllipseInRect(ctx, selfBounds);
}
@end
このようなマスクレイヤーを画像ビューに適用するには、次のようなコードを使用できます。
MyMaskLayer *maskLayer = [[MyMaskLayer alloc] init];
maskLayer.bounds = self.view.bounds;
[maskLayer setNeedsDisplay];
self.imageView.layer.mask = maskLayer;
さて、このようなレンダリングからピクセルデータを取得したい場合は、ピクセルバッファを制御するビットマップに裏打ちされたCGContextにレンダリングするのが最善です。レンダリング後、バッファ内のピクセルデータを検査できます。これは、ビットマップコンテキストを作成し、レイヤーとマスクをそのビットマップコンテキストにレンダリングする例です。ピクセルデータ用に独自のバッファを提供しているので、レンダリング後にバッファを調べてRGBA値を取得できます。
const CGRect imageViewBounds = self.imageView.bounds;
const size_t imageWidth = CGRectGetWidth(imageViewBounds);
const size_t imageHeight = CGRectGetHeight(imageViewBounds);
const size_t bytesPerPixel = 4;
// Allocate your own buffer for the bitmap data. You can pass NULL to
// CGBitmapContextCreate and then Quartz will allocate the memory for you, but
// you won't have a pointer to the resulting pixel data you want to inspect!
unsigned char *bitmapData = (unsigned char *)malloc(imageWidth * imageHeight * bytesPerPixel);
CGContextRef context = CGBitmapContextCreate(bitmapData, imageWidth, imageHeight, 8, bytesPerPixel * imageWidth, rgbColorSpace, kCGImageAlphaPremultipliedLast);
// Render the image into the bitmap context.
[self.imageView.layer renderInContext:context];
// Set the blend mode to destination in, pixels become "destination * source alpha"
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
// Render the mask into the bitmap context.
[self.imageView.layer.mask renderInContext:context];
// Whatever you like here, I just chose the middle of the image.
const size_t x = imageWidth / 2;
const size_t y = imageHeight / 2;
const size_t pixelIndex = y * imageWidth + x;
const unsigned char red = bitmapData[pixelIndex];
const unsigned char green = bitmapData[pixelIndex + 1];
const unsigned char blue = bitmapData[pixelIndex + 2];
const unsigned char alpha = bitmapData[pixelIndex + 3];
NSLog(@"rgba: {%u, %u, %u, %u}", red, green, blue, alpha);