Tablib, NSImage zu TagLib:BytesVector

  • Tablib, NSImage zu TagLib:BytesVector

    Hi,

    ich habe folgenden Code:

    Quellcode

    1. if (_artwork) {
    2. //Init data to png transformer
    3. NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithCGImage:[_artwork CGImageForProposedRect:NULL
    4. context:nil
    5. hints:nil]];
    6. //Art work as png data
    7. NSData *pngData = [bits representationUsingType:NSPNGFileType properties:nil];
    8. //Set artwork with TagLib
    9. //Init TagLib audio object
    10. TagLib::MPEG::File audioFile(_filePath.UTF8String);
    11. //Enable neccessary tag type
    12. TagLib::ID3v2::Tag *tag = audioFile.ID3v2Tag(true);
    13. //Init artwoork frame
    14. TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;
    15. //Configure artwork frame
    16. frame->setMimeType("image/png");
    17. TagLib::ByteVector *bytes = new TagLib::ByteVector((const char *)pngData.bytes);
    18. frame->setPicture(*bytes);
    19. //Add artwork to audio file
    20. tag->addFrame(frame);
    21. audioFile.save();
    22. }
    Alles anzeigen


    Ich konvertiere ein NSImage zu NSData, erstelle daraus NSData vom Typ PNG und erzeuge einen neuen BytesVector. Allerdings klappt das gar nicht.

    NSLog(@"%s", (const char *)pngData.bytes); liefert: "âPNG
    "
    Und NSLog(@"%@", pngData); liefter mir ganz normal die Daten, also das Objekt ist nicht leer oder so. DIe Konvertierung von void* zu const char* scheint das Problem zu sein. Wo liegt der Fehler?

    Viele Grüße
  • Ich habe meinen Code nochmals überarbeitet und über Google nach Lösungen gesucht, aber so richtig komme ich nicht voran.

    Quellcode

    1. //Init data to png transformer
    2. NSBitmapImageRep *pngBitmap = [[NSBitmapImageRep alloc] initWithCGImage:[_artwork CGImageForProposedRect:NULL
    3. context:nil
    4. hints:nil]];
    5. //Art work as png data
    6. NSData *pngData = [pngBitmap representationUsingType:NSPNGFileType properties:nil];
    7. uint length = (uint)[NSNumber numberWithUnsignedInteger:pngData.length].unsignedIntValue;
    8. const char *buffer;
    9. [pngData getBytes:&buffer length:pngData.length];
    10. //Set artwork with TagLib
    11. //Init TagLib audio object
    12. TagLib::MPEG::File audioFile(_filePath.UTF8String);
    13. //Enable neccessary tag type
    14. TagLib::ID3v2::Tag *tag = audioFile.ID3v2Tag(true);
    15. //Init artwoork frame
    16. TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;
    17. //Configure artwork frame
    18. frame->setMimeType("image/png");
    19. TagLib::ByteVector *bytes = new TagLib::ByteVector(*buffer, length);
    20. frame->setPicture(*bytes);
    21. //Add artwork to audio file
    22. tag->addFrame(frame);
    23. audioFile.save();
    24. //});
    25. delete frame;
    26. delete bytes;
    Alles anzeigen


    Jetzt sürzt das Programm allerdings ab, sobald audioFile erzeugt erzeugt wird und Xcode sagt EXC_BAD_ACESS. Wo liegt das Problem? Der Pfad ist gültig, keine Leerzeichen (falls das Probleme geben sollte) und da liegt definitiv eine MP3-Datei ohne Coverartwork. Ich verstehe die Welt nicht mehr 8|
  • Sag mir bitte wo genau es hakt bzw. wo deiner Meinung nach das Problem ist.

    Ich habe diesen Code vor 1 oder 2 Jahren von einer Website kopiert (Quelle weiß ich nicht mehr) weil ich, wie man wohl sieht nicht viel Ahnung von C++ und den primitiven Datentype habe.
    Ursprünlich sah der Code in etwas so aus:

    Quellcode

    1. class ImageFile : public TagLib::File {
    2. public:
    3. ImageFile(const char *file) : TagLib::File(file) {
    4. }
    5. TagLib::String mimeType() const {
    6. TagLib::String fileName = name();
    7. if(fileName.substr(fileName.size() - 4, 4).upper() == ".PNG")
    8. return "image/png";
    9. else if(fileName.substr(fileName.size() - 4, 4).upper() == ".JPG" || fileName.substr(fileName.size() - 5, 5).upper() == ".JPEG")
    10. return "image/jpeg";
    11. return TagLib::String::null;
    12. }
    13. TagLib::ByteVector data() {
    14. return readBlock(length());
    15. }
    16. bool isValid() const {
    17. return isOpen() && !mimeType().isNull();
    18. }
    19. private:
    20. virtual TagLib::Tag *tag() const {
    21. return 0;
    22. }
    23. virtual TagLib::AudioProperties *audioProperties() const {
    24. return 0;
    25. }
    26. virtual bool save() {
    27. return false;
    28. }
    29. };
    30. @implementation SomeClass
    31. - (void)someMethod {
    32. NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithCGImage:[_artwork CGImageForProposedRect:NULL
    33. context:nil
    34. hints:nil]];
    35. //Art work as png data
    36. NSData *pngData = [bits representationUsingType:NSPNGFileType properties:nil];
    37. //Init path to atwork
    38. NSString *pathToArtwork = [NSString stringWithFormat:@"%@/%@.png", _enclosingFolder, [[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970] md5]];
    39. //Write png data to temp folder
    40. [pngData writeToFile:pathToArtwork atomically:NO];
    41. //Set artwork with TagLib
    42. //Init TagLib audio object
    43. TagLib::MPEG::File audioFile(self.filePath.UTF8String);
    44. //Init Imagefile object
    45. ImageFile imageFile(pathToArtwork.UTF8String);
    46. //Enable neccessary tag type
    47. TagLib::ID3v2::Tag *tag = audioFile.ID3v2Tag(true);
    48. //Init artwoork frame
    49. TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;
    50. //Configure artwork frame
    51. frame->setMimeType(imageFile.mimeType());
    52. frame->setPicture(imageFile.data());
    53. //Add artwork to audio file
    54. tag->addFrame(frame);
    55. audioFile.save();
    56. @end
    Alles anzeigen


    Das funktioniert ohne Mucken, ich fand es allerdings nicht besonders schön immer eine Bilddatei zu speichern und dann wieder zu laden, deswegen habe ich nach einer Möglichkeit gesucht, das NSData-Objekt direkt zu konvertieren ohne den Umweg über eine Bilddatei.