Bilder skalieren über CoreImage?

  • Bilder skalieren über CoreImage?

    Moin Leute!

    Zur Zeit skaliere ich Bilder auf folgende Art:

    Quellcode

    1. NSBitmapImageRep* newRep =
    2. [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
    3. pixelsWide:widNeu
    4. pixelsHigh:higNeu
    5. bitsPerSample:8
    6. samplesPerPixel:4
    7. hasAlpha:YES
    8. isPlanar:NO
    9. colorSpaceName:NSCalibratedRGBColorSpace
    10. bytesPerRow:0
    11. bitsPerPixel:0 ];
    12. [NSGraphicsContext saveGraphicsState];
    13. NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:newRep];
    14. [NSGraphicsContext setCurrentContext:context];
    15. [curImg drawInRect:NSMakeRect( 0, 0, [newRep pixelsWide], [newRep pixelsHigh] )];
    16. [NSGraphicsContext restoreGraphicsState];
    Alles anzeigen
    Das ist jedoch relativ langsam! :(
    Daher habe ich mich gefragt wie das wohl schneller gehen würde.
    Ich habe mit CoreImage bislang noch nichts gemacht. Geht das skalieren von Bildern damit schneller?
    Gibt es irgendwo Performance Benchmarks oder so?

    Viele Grüße!
  • Wieso machst du das nicht einfach in dieser Art:

    Quellcode

    1. [myImage setScalesWhenResized:YES];
    2. [myImage setSize:NSMakeSize(newWidth, newHeight)];

    Gleich mal so etliche Zeilen Code gespart... Zu Core Image: Keine Ahnung, ob das damit überhaupt geht oder Performance-mäßig besser ist... Ist auf jeden Fall nicht so der eigentliche Zweck von CI. NSImage hat für den Normalgebrauch auch einige Vorteile -> höhere Abstraktionsebene...
  • Original von omz
    Wieso machst du das nicht einfach in dieser Art:

    Quellcode

    1. [myImage setScalesWhenResized:YES];
    2. [myImage setSize:NSMakeSize(newWidth, newHeight)];

    Das funktioniert nur, wenn das 'NSImage' auch etwas zum Zeichnen hat. Ansonsten greift die Methode nicht auf die eigentlichen Bilddaten im 'rep' durch.
    Der Ansatz von 'Jaxx0r' ist daher schon richtig.
    I would be embarrassed if they did not spy on me.
  • RE: Bilder skalieren über CoreImage?

    Der Kommentar von Tom911 ist schon richtig: Wenn es CI kann, können wir davon ausgehen, dass Apple es ebenso in 'NSImage' macht.
    CI generell brauchst Du, um bessere Qualität zu erzielen, mal schnell ein 'blur' oder leichtes 'sharpen'. Ansonsten ist der Aufwand schon recht groß.
    Was mir auffiel:
    Du gehst über den 'NSGraphicsContext'. Es könnte helfen, es mit einem 'lockFocus' zu probieren:

    Quellcode

    1. ...
    2. [curImg lockFocus];
    3. [curImg drawInRect:NSMakeRect( 0, 0, [newRep pixelsWide], [newRep pixelsHigh] )];
    4. [curImg unlockFocus];
    5. ...
    Vielleicht liegt es daran.
    I would be embarrassed if they did not spy on me.
  • RE: Bilder skalieren über CoreImage?

    Richtig: Ich dachte 'curImg' gehört zu 'NSImage', ist leider nicht im Code erklärt.
    Also müsste es noch etwa so:

    Quellcode

    1. NSImage *curImg = [[NSImage alloc] initWithSize: NSMakeSize(widNeu, higNeu)];

    am Anfang stehen, und auf das "NSBitmapImageRep" könntest Du ganz verzichten.
    I would be embarrassed if they did not spy on me.
  • RE: Bilder skalieren über CoreImage?

    ich skalier btw so:

    Quellcode

    1. NSImage *img = [[NSImage alloc] initWithContentsOfFile:picturePath];
    2. NSImage *scaleImg = [[NSImage alloc] initWithSize:size];
    3. [scaleImg lockFocus];
    4. [img drawInRect:NSMakeRect(0.0,0.0,size.width,size.height)
    5. fromRect:NSMakeRect(0.0,0.0,[img size].width,[img size].height)
    6. operation:NSCompositeCopy fraction:1.0];
    7. [scaleImg unlockFocus];

    und hol mir meine Rep über diese zeile:

    Quellcode

    1. NSBitmapImageRep *tempRep = [NSBitmapImageRep imageRepWithData:[scaleImg TIFFRepresentation]];


    btw skalier ich hauptsächlich deswegen so weil das [newImage setScalesWhenResized:YES]; bei mir nicht so funktioniert hat das die entsprechende Bitmap resized geliefert wurde - vermutlich wird erst beim zeichnen skaliert - ich hab das aber nicht lang getestet sondern einfach wie oben umgebaut
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!
  • RE: Bilder skalieren über CoreImage?

    Original von chartus
    und hol mir meine Rep über diese zeile:

    Quellcode

    1. NSBitmapImageRep *tempRep = [NSBitmapImageRep imageRepWithData:[scaleImg TIFFRepresentation]];


    Wenn es nur um die unter dem 'NSImage' liegende Representation geht, müsste diese ausreichend sein:

    Quellcode

    1. NSImageRep *tempRep = [scaleImg bestRepresentationForDevice:nil];
    Mit Deiner Zeile wird eine komplett neue Representation erzeugt, und damit im Prinzip ein neues Bild.
    I would be embarrassed if they did not spy on me.
  • Original von oddysseey
    vielleicht wird dann die bitmap "refreshed"?

    Vieleicht, vielleicht auch nicht. Im Cocoa Drawing Guide liest es sich so:
    You can change the size of an image at any time using the setSize: method of either NSImage or NSImageRep. ... Changing this value therefore changes the size of the image as it is drawn in one of your views. This change typically affects only the cached copy of the image data, if one exists.

    Das meinte ich, als ich weiter oben anmerkte, das ein 'NSImage' etwas zum Zeichnen braucht. In der Regel trifft das nur zu, wenn ein 'View' vorhanden ist.
    I would be embarrassed if they did not spy on me.
  • RE: Bilder skalieren über CoreImage?

    Dann schau Dir das noch mal an, ist sehr ähnlich zu 'Chartus':

    Quellcode

    1. - (NSImage *) resizedImageFromImage:(NSImage*)sourceImage withSize:(NSSize)resize
    2. {
    3. NSImage *resizedImage = [[NSImage alloc] initWithSize: resize];
    4. NSSize originalSize = [sourceImage size];
    5. [resizedImage lockFocus];
    6. [sourceImage drawInRect: NSMakeRect(0, 0, resize.width, resize.height)
    7. fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height)
    8. operation: NSCompositeSourceOver fraction: 1.0];
    9. [resizedImage unlockFocus];
    10. return [resizedImage autorelease];
    11. }
    Alles anzeigen
    Der wesentliche Unterschied ist nur 'NSCompositeSourceOver'. Dein altes Image bleibt Dir erhalten, kein Umweg über Reps und 'graphicContext'.
    HTH. W.
    I would be embarrassed if they did not spy on me.
  • RE: Bilder skalieren über CoreImage?

    Original von longW
    Wenn es nur um die unter dem 'NSImage' liegende Representation geht, müsste diese ausreichend sein:

    Quellcode

    1. NSImageRep *tempRep = [scaleImg bestRepresentationForDevice:nil];
    Mit Deiner Zeile wird eine komplett neue Representation erzeugt, und damit im Prinzip ein neues Bild.


    hm das stimmt - aber das war gewollt.
    in dem falle hol ich mir ein bild skalier es auf ein bestimmtes setup und speichere nur intern die Rep in meinem modell
    die beiden NSImages werden im anschluß sofort wieder freigegeben (darum auch nicht autoreleased :) )

    die bilder werden btw nirgend gezeichnet - wird nur interen mit den bitmapdaten gearbeitet
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!