#import <Cocoa/Cocoa.h>
#import <Accelerate/Accelerate.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//---------- 画像のURLを取得 image.tif がデスクトップにあると仮定します。----------/
NSString *path
= [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/image.tif"];
NSURL *imageURL = [NSURL fileURLWithPath:path];
// imageURL にある画像からソースを作成。
CGImageSourceRef sourceRef
= CGImageSourceCreateWithURL((CFURLRef)imageURL, NULL);
// ソースが作られなければ終了。
if (sourceRef == NULL) {
return EXIT_FAILURE;
}
// ソースからイメージを作成
CGImageRef imageRef
= CGImageSourceCreateImageAtIndex(sourceRef,0,NULL);
// もういらない。
CFRelease(sourceRef);
// イメージが作成できなければ終了。
if (imageRef == NULL) {
return EXIT_FAILURE;
}
//-------------------- イメージの情報を取得 --------------------//
size_t bpr = CGImageGetBytesPerRow(imageRef);
size_t height = CGImageGetHeight(imageRef);
size_t width = CGImageGetWidth(imageRef);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef);
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;
CGBitmapInfo infoMask = kCGBitmapFloatComponents |
kCGBitmapByteOrderMask;
// 今回はごめん。
if ((bitmapInfo & infoMask) > 0 ||
colorSpaceModel != kCGColorSpaceModelRGB) {
CGImageRelease(imageRef);
return EXIT_FAILURE;
}
//-------------------- ビットマップを取得する --------------------//
CGDataProviderRef provider = CGImageGetDataProvider(imageRef);
NSData *tmpData = (NSData *)CGDataProviderCopyData(provider);
// もういらない
CGImageRelease(imageRef);
unsigned char *bitmapData
= (unsigned char *)malloc([tmpData length] * sizeof(unsigned char));
[tmpData getBytes:bitmapData length:[tmpData length]];
// もういらない
[tmpData release];
// -------------------- vImage_Bufferの作成 --------------------//
vImage_Buffer org, src, dist;
vImage_Error error;
org.data = bitmapData;
org.height = (vImagePixelCount)height;
org.width = (vImagePixelCount)width;
org.rowBytes = bpr;
src.data = (unsigned char *)calloc(width * height * 4, sizeof(unsigned char));
src.height = (vImagePixelCount)height;
src.width = (vImagePixelCount)width;
src.rowBytes = width * 4;
dist.data = (unsigned char *)calloc(width * height * 4, sizeof(unsigned char));
dist.height = (vImagePixelCount)height;
dist.width = (vImagePixelCount)width;
dist.rowBytes = width * 4;
// RGB,RGBA,ARGB -> ARGB にする。
if (alphaInfo == kCGImageAlphaNone) {
vImageConvert_RGB888toARGB8888(&org, NULL, 255, &src, FALSE, 0);
}
else if (alphaInfo == kCGImageAlphaLast ||
alphaInfo == kCGImageAlphaPremultipliedLast ||
alphaInfo == kCGImageAlphaNoneSkipLast){
uint8_t permutMap[4] = {3,0,1,2};
vImagePermuteChannels_ARGB8888(&org, &src, permutMap, 0);
}
else if (alphaInfo == kCGImageAlphaFirst ||
alphaInfo == kCGImageAlphaPremultipliedFirst ||
alphaInfo == kCGImageAlphaNoneSkipFirst){
uint8_t permutMap[4] = {0,1,2,3};
vImagePermuteChannels_ARGB8888(&org, &src, permutMap, 0);
}
// premultiply されてるものは解除。
if (alphaInfo == kCGImageAlphaPremultipliedFirst ||
alphaInfo == kCGImageAlphaPremultipliedLast) {
vImageUnpremultiplyData_ARGB8888(&src, &src, 0);
}
// もういらない
free(bitmapData);
// -------------------- 畳み込みの計算 --------------------//
// 3 x 3 カーネルを作成
int16_t kernel[9] = {
-2, -2,-2,
-2, 1, 2,
2, 2, 2
};
// 除数の作成
int32_t divisor = 0;
for (NSInteger i = 0; i < 9; ++i) {
divisor += kernel[i];
}
// バックグランド・カラーの作成(使わない)
Pixel_8888 bgColor = {0,0,0,0};
// 畳み込みの計算
error = vImageConvolve_ARGB8888(&src,
&dist,
NULL,
0,
0,
kernel,
3,
3,
divisor,
bgColor,
kvImageEdgeExtend +
kvImageLeaveAlphaUnchanged);
// エラーがでたら終了
if (error < 0) {
free(src.data);
free(dist.data);
return EXIT_FAILURE;
}
// premultiply されてたものは元にもどす。
if (alphaInfo == kCGImageAlphaPremultipliedFirst ||
alphaInfo == kCGImageAlphaPremultipliedLast) {
vImagePremultiplyData_ARGB8888(&dist, &dist, 0);
}
// もういらない。
free(src.data);
//-------------------- 書き出し用の画像を作成 --------------------//
CGContextRef context
= CGBitmapContextCreate(dist.data,
width,
height,
8,
width * 4,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGImageRef cgImage = CGBitmapContextCreateImage(context);
// もういらない
CGContextRelease(context);
NSBitmapImageRep *imageRep
= [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
// もういらない
CGImageRelease(cgImage);
free(dist.data);
NSData *outputData = [imageRep TIFFRepresentation];
NSString *pathToWrite
= [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/out.tif"];
[outputData writeToFile:pathToWrite
atomically:YES];
[imageRep release];
[pool drain];
return EXIT_SUCCESS;
}
0 件のコメント:
コメントを投稿