Est-ce que quelqu'un sait quelles sont les limites sur la taille de l'image avec des CIFilters personnalisés? J'ai créé un filtre qui fonctionne comme prévu lorsque les images atteignent 2 méga pixels, mais produit des résultats très étranges lorsque les images sont plus grandes. J'ai testé cela à la fois dans mon application de cacao ainsi que dans le compositeur de quartz. Le filtre que j'ai développé est un filtre de distorsion de type géométrique qui (je pense) nécessite une ROI et un DOD qui couvre toute l'image d'entrée. J'ai créé ce filtre pour remapper des images panoramiques, donc je voudrais que cela fonctionne sur de très grandes images (50-100 méga pixels). En guise de simple test, le CIFilter suivant (peut être utilisé dans Quartz Composer) traduit simplement l'image de sorte que le coin inférieur gauche des images soit traduit au centre (je sais que cela peut être fait avec un transformation affine mais j'ai besoin d'effectuer une telle opération dans un filtre plus complexe). Ce filtre fonctionne comme prévu lorsque l'image est 2000x1000 mais produit des résultats impairs lorsque l'image d'entrée est 4000x2000 pixels. Le problème est que la traduction ne déplace pas exactement le coin vers le centre ou que la sortie de l'image est complètement disparue. J'ai remarqué d'autres problèmes bizarres avec des filtres plus compliqués sur de grandes images mais je pense que ce simple filtre illustre mon problème et peut être reproduit dans Quartz Composer.taille d'image maximale dans CIFilter/CIKernel?
kernel vec4 equidistantProjection(sampler src, __color color)
{
vec2 coordinate = samplerCoord(src);
vec2 result;
vec4 outputImage;
result.x = (coordinate.x - samplerSize(src).x/2.0);
result.y = (coordinate.y - samplerSize(src).y/2.0);
outputImage = unpremultiply(sample(src,result));
return premultiply(outputImage);
}
Le même comportement étrange apparaît lorsque vous utilisez le travail coordonne la place des coordonnées de l'échantillonneur mais dans ce cas, l'erreur se produit pour les images de taille 2000x1000 mais fonctionne très bien pour les images de taille 1000x500
kernel vec4 equidistantProjection(sampler src, __color color, vec2 destinationDimensions)
{
vec2 coordinate = destCoord();
vec2 result;
vec4 outputImage;
result.x = (coordinate.x - destinationDimensions.x/2.0);
result.y = (coordinate.y - destinationDimensions.y/2.0);
outputImage = unpremultiply(sample(src,result));
outputImage = unpremultiply(sample(src,samplerTransform(src, result)));
return premultiply(outputImage);
}
Pour référence J'ai ajouté à la partie Objective-C de la méthode - (CIImage *)outputImage
de mon filtre ce qui suit pour que le DOD soit l'image d'entrée entière.
- (CIImage *)outputImage
{
CISampler *src = [CISampler samplerWithImage: inputImage];
NSArray * outputExtent = [NSArray arrayWithObjects:
[NSNumber numberWithInt:0],
[NSNumber numberWithInt:0],
[NSNumber numberWithFloat:[inputImage extent].size.width],
[NSNumber numberWithFloat:[inputImage extent].size.height],nil];
return [self apply: filterKernel, src, inputColor, zoom, viewBounds, inputOrigin,
kCIApplyOptionDefinition, [src definition], kCIApplyOptionExtent, outputExtent, nil];
}
De plus j'ai ajouté la méthode suivante pour définir le retour sur investissement que j'appelle dans ma méthode - (id)init
avec ceci: [filterKernel setROISelector:@selector(regionOf:destRect:userInfo:)];
- (CGRect) regionOf:(int)samplerIndex destRect:(CGRect)r userInfo:obj
{
return r;
}
Toute aide ou des conseils sur cette question seraient grandement appréciés. Je suis sûr que les CIFilters peuvent travailler avec des images plus grandes car j'ai utilisé la CIBumpDistortion avec des images de plus de 50 mégapixels, donc je dois faire quelque chose de mal. Des idées?
Existe-t-il un moyen de connaître l'origine de l'image en mosaïque a priori? Si vous passez dans l'extension 4-d (origine x, origine y, largeur, hauteur), pouvez-vous déterminer par programme comment CoreImage va découper l'image en parties pour savoir où l'origine sera pour chaque segment? Ou est-ce que je manque quelque chose? Ce que j'ai fait avec des résultats décents est d'utiliser destCoord puis samplerTransform en passant explicitement toute l'étendue de l'image d'entrée en tant que ROI. Cela fonctionne bien tant que l'image d'entrée est suffisamment petite. –
J'ai modifié mon message avec un exemple – Gobra