Domanda

Voglio utilizzare nella mia app an costume filtro.Ora so che devo usare Immagine centrale framework, ma non sono sicuro che sia la strada giusta.Il framework Core Image utilizza per Mac OS e dentro iOS5.0 - Non sono sicuro che possa essere utilizzato per effetti CIFilter personalizzati.Potete aiutarmi con questo problema?Ringrazia tutti!

È stato utile?

Soluzione

obsoleto

Non puoi creare i tuoi kernel / filtri personalizzati ancora in iOS.Vedi http://developer.apple.COM / Biblioteca / MAC / # Documentazione / Graphicsimaging / Concettuale / CoreImaging / Ci_intro / ci_intro.html , in particolare:

.

Sebbene questo documento sia incluso nella libreria di riferimento, ha Non è stato aggiornato in dettaglio per iOS 5.0.Una prossima revisione sarà Dettagli le differenze nell'immagine centrale su iOS.In particolare, la chiave la differenza è che immagine principale su iOS non include la capacità di Crea filtri immagine personalizzata .

(Bolding Mine)

Altri suggerimenti

Come afferma Adam, Attualmente l'immagine principale su IOS non supporta i kernel personalizzati come il più vecchio implementazione Mac lo fa. Questo limita ciò che puoi fare con il quadro per essere una specie di combinazione di filtri esistenti.

(Aggiornamento: 2/13/2012)

Per questo motivo, ho creato un quadro open source per iOS chiamato GPuimage , che ti permette Creare filtri personalizzati da applicare a immagini e video utilizzando Shader di frammenti OpenGL ES 2.0. Descrivo di più su come questo framework opera in Il mio post sull'argomento . Fondamentalmente, è possibile fornire i tuoi shader del frammento di GLSL (OpenGL Shading Language) personalizzato per creare un filtro personalizzato e quindi eseguire quel filtro contro immagini statiche o video live. Questo framework è compatibile con tutti i dispositivi IOS che supporta OpenGL ES 2.0 e possono creare applicazioni che mirano iOS 4.0.

Ad esempio, è possibile impostare il filtraggio del video in diretta utilizzando il codice come quanto segue:

GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, viewHeight)];

// Add the view somewhere so it's visible

[videoCamera addTarget:thresholdFilter];
[customFilter addTarget:filteredVideoView];

[videoCamera startCameraCapture];
.

Come esempio di un programma di shader framment personalizzato che definisce un filtro, quanto segue applica un effetto tono seppia:

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    lowp vec4 outputColor;
    outputColor.r = (textureColor.r * 0.393) + (textureColor.g * 0.769) + (textureColor.b * 0.189);
    outputColor.g = (textureColor.r * 0.349) + (textureColor.g * 0.686) + (textureColor.b * 0.168);    
    outputColor.b = (textureColor.r * 0.272) + (textureColor.g * 0.534) + (textureColor.b * 0.131);

    gl_FragColor = outputColor;
}
.

La lingua utilizzata per la scrittura dei kernel di immagine di base personalizzati sul Mac è molto simile a GLSL. Infatti, sarai in grado di fare alcune cose che non puoi in un'immagine del Desktop Core, perché la lingua del kernel dell'immagine principale non ha alcune cose che GLSL ha (come ramificazione).

La risposta accettata originale è ammortizzata.Da IOS 8 è possibile creare kernel personalizzati per i filtri.Puoi trovare maggiori informazioni su questo in:

Puoi creare filtri personalizzati per iOS più facilmente rispetto a un plug-in Image Unit per MacOS X, al punto che sarebbero preferiti, anche se i plug-in Image Unit fossero supportati da iOS.Il problema è che non puoi effettivamente "impacchettarli" o raggrupparli in altro modo come una risorsa come i plug-in Image Unit;devi esporre il tuo codice sorgente agli sviluppatori che li utilizzano.Inoltre, sono utili solo agli sviluppatori;non puoi distribuirli agli utenti finali delle app grafiche iOS nello stesso modo in cui puoi distribuirli per le app grafiche MacOS X che importano filtri Core Image di terze parti.Per questo, devi incorporarli in un'estensione di fotoritocco.

Tuttavia, anche l'elaborazione delle immagini con un filtro Core Image personalizzato per iOS è più semplice che con un plug-in Image Unit.Non è prevista alcuna importazione, seguita dal compito confuso di configurare .plist, file di descrizione e quant'altro.

Un filtro Core Image personalizzato per iOS è semplicemente una classe Cocoa Touch che è una sottoclasse di CIFilter;in esso, si specificano i parametri di input (sempre almeno l'immagine), le impostazioni degli attributi personalizzati e i relativi valori predefiniti, quindi qualsiasi combinazione di filtri Immagine principale incorporati o personalizzati.Se vuoi aggiungere un kernel OpenGL alla pipeline di elaborazione delle immagini, aggiungi semplicemente un metodo CIKernel, che carica il .cikernel che scrivi in ​​un file separato.

La bellezza di questo particolare metodo per sviluppare un filtro immagine core personalizzato per iOS è che i filtri personalizzati vengono istanziati e chiamati allo stesso modo dei filtri integrati:

CIFilter* PrewittKernel = [CIFilter filterWithName:@"PrewittKernel"];

CIImage *result = [CIFilter filterWithName:@"PrewittKernel" keysAndValues:kCIInputImageKey, self.inputImage, nil].outputImage;

Ecco un semplice esempio che utilizza OpenGL per applicare l'operatore Prewitt a un'immagine;prima, la Cocoa Touch Class (sottoclasse CIFilter), quindi il file CIKernel (contenente il codice OpenGL ES 3.0):

Il file di intestazione:

//
//  PrewittKernel.h
//  Photo Filter
//
//  Created by James Alan Bush on 5/23/15.
//
//

#import <CoreImage/CoreImage.h>

@interface PrewittKernel : CIFilter
{
    CIImage *inputImage;
}

@property (retain, nonatomic) CIImage *inputImage;

@end

Il dossier di implementazione:

//
//  PrewittKernel.m
//  Photo Filter
//
//  Created by James Alan Bush on 5/23/15.
//
//

#import <CoreImage/CoreImage.h>

@interface PrewittKernel : CIFilter
{
    CIImage *inputImage;
}

@property (retain, nonatomic) CIImage *inputImage;

@end


@implementation PrewittKernel

@synthesize inputImage;

- (CIKernel *)prewittKernel
{
    static CIKernel *kernelPrewitt = nil;

    NSBundle    *bundle = [NSBundle bundleForClass:NSClassFromString(@"PrewittKernel")];
    NSStringEncoding encoding = NSUTF8StringEncoding;
    NSError     *error = nil;
    NSString    *code = [NSString stringWithContentsOfFile:[bundle pathForResource:@"PrewittKernel" ofType:@"cikernel"] encoding:encoding error:&error];

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        kernelPrewitt = [CIKernel kernelWithString:code];
    });

    return kernelPrewitt;
}

- (CIImage *)outputImage
{
    CIImage *result = self.inputImage;
    return [[self prewittKernel] applyWithExtent:result.extent roiCallback:^CGRect(int index, CGRect rect) {
        return CGRectMake(0, 0, CGRectGetWidth(result.extent), CGRectGetHeight(result.extent));
    } arguments:@[result]];
}

@end

Il CIKernel (OpenGL ES 3.0):

/* PrewittKernel.cikernel */

kernel vec4 prewittKernel(sampler image)
{
    vec2 xy = destCoord();
    vec4 bottomLeftIntensity = sample(image, samplerTransform(image, xy + vec2(-1, -1)));
    vec4 topRightIntensity = sample(image, samplerTransform(image, xy + vec2(+1, +1)));
    vec4 topLeftIntensity = sample(image, samplerTransform(image, xy + vec2(+1, -1)));
    vec4 bottomRightIntensity = sample(image, samplerTransform(image, xy + vec2(-1, +1)));
    vec4 leftIntensity = sample(image, samplerTransform(image, xy + vec2(-1, 0)));
    vec4 rightIntensity = sample(image, samplerTransform(image, xy + vec2(+1, 0)));
    vec4 bottomIntensity = sample(image, samplerTransform(image, xy + vec2(0, -1)));
    vec4 topIntensity = sample(image, samplerTransform(image, xy + vec2(0, +1)));
    vec4 h = vec4(-topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity);
    vec4 v = vec4(-bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity);
    float h_max = max(h.r, max(h.g, h.b));
    float v_max = max(v.r, max(v.g, v.b));
    float mag = length(vec2(h_max, v_max)) * 1.0;

    return vec4(vec3(mag), 1.0);
}

Ecco un altro filtro che genera una maschera di contrasto sottraendo (o, piuttosto, differenziando) un'immagine sfocata gaussiana dall'originale utilizzando i filtri Core Image integrati: nessun codice kernel Core Image (OpenGL);mostra come specificare e utilizzare un attributo personalizzato, ovvero il raggio della sfocatura gaussiana:

Il file di intestazione:

//
//  GaussianKernel.h
//  Chroma
//
//  Created by James Alan Bush on 7/12/15.
//  Copyright © 2015 James Alan Bush. All rights reserved.
//

#import <CoreImage/CoreImage.h>

@interface GaussianKernel : CIFilter
{
    CIImage *inputImage;
    NSNumber *inputRadius;
}

@property (retain, nonatomic) CIImage *inputImage;
@property (retain, nonatomic) NSNumber *inputRadius;

@end

Il dossier di implementazione:

//
//  GaussianKernel.m
//  Chroma
//
//  Created by James Alan Bush on 7/12/15.
//  Copyright © 2015 James Alan Bush. All rights reserved.
//

#import "GaussianKernel.h"

@implementation GaussianKernel

@synthesize inputImage;
@synthesize inputRadius;

+ (NSDictionary *)customAttributes
{
    return @{
             @"inputRadius" :
                 @{
                     kCIAttributeMin       : @3.0,
                     kCIAttributeMax       : @15.0,
                     kCIAttributeDefault   : @7.5,
                     kCIAttributeType      : kCIAttributeTypeScalar
                     }
             };
}

- (void)setDefaults
{
    self.inputRadius = @7.5;
}

    - (CIImage *)outputImage
    {
        CIImage *result = self.inputImage;

        CGRect rect = [[GlobalCIImage sharedSingleton].ciImage extent];
        rect.origin = CGPointZero;
        CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width, rect.size.height);
        CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width W:rect.size.height];

    result = [[CIFilter filterWithName:@"CIGaussianBlur" keysAndValues:kCIInputImageKey, result, @"inputRadius", [NSNumber numberWithFloat:inputRadius.floatValue], nil].outputImage imageByCroppingToRect:cropRectLeft];

    result = [CIFilter filterWithName:@"CICrop" keysAndValues:@"inputImage", result, @"inputRectangle", cropRect, nil].outputImage;

    result = [CIFilter filterWithName:@"CIDifferenceBlendMode" keysAndValues:kCIInputImageKey, result, kCIInputBackgroundImageKey, result, nil].outputImage;

        return result;
    }

    @end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top