std::vector<unsigned char> in (const char*) casten
-
jo!! Ich bin gerade daran ein Game zu programmieren mit SFML http://www.sfml-dev.org/. Bin erst gerade darauf umgestiegen von SDL.
Ich habe eine Library namens LodePNG
http://members.gamedev.net/lode/projects/LodePNG/ mit der ich ein Bild als Binär decodieren kann. Der sinn dahinter ist, dass ich dieses Bild in einem File, binär abspeichern kann und es wieder auslesen. Mein Problem ist dass die Decodierung auf ein "vector<unsigned char>" zurückgegeben wird. Und um das Bild mit SFML zu laden muss es aber "const char*" sein.Ich währe auch froh um andere Forschläge, um Bilder in Dateien zu packen. Der Sinn dahinter ist, dass mir Niemand kann die Grafiken klauen, oder der Spieler die nachkommenden Game-Levels nicht im Ordner nachschauen gehen kann. Das ganze ist auchnoch eine Estetische Sache.
-
Da ist mir wohl jemand zuvor gekommen!!
Ich würde mir eine neue Glaskugel kaufen!!
aber Danke für deine Bemühung!
-
Du könntest natürlich auch das PNG von SFML lesen und schreiben lassen, schliesslich bietet es diese Funktionalität (
sf::Image::LoadFromFile()
undsf::Image::SaveToFile()
). Um das Bild unkenntlich zu machen, könntest du vor dem Speichern eine Art Verschlüsselung darüber laufen lassen. Dafür modifizierst du die einzelnen Pixel imsf::Image
. Nach dem Laden machst du das wieder rückgängig. Nur so eine Idee...Falls du deine Vorgehensweise beibehältst, könntest du den
std::vector<unsigned char>
in einenstd::vector<char>
umkopieren:std::vector<unsigned char> Source; std::vector<char> Dest(Source.begin(), Source.end()); const char* PixelArray = &Dest[0]
Alternativ kannst du den Speicher reinterpretieren, das sollte bei
char
undunsigned char
eigentlich gehen:std::vector<unsigned char> Source; const char* PixelArray = reinterpret_cast<const char*>(&Source[0]);
-
Nexus schrieb:
Um das Bild unkenntlich zu machen, könntest du vor dem Speichern eine Art Verschlüsselung darüber laufen lassen. Dafür modifizierst du die einzelnen Pixel im
sf::Image
. Nach dem Laden machst du das wieder rückgängig. Nur so eine Idee...Verschlüsseln der PNG-Bytes wäre besser, da sonst der PNG encoder das verfremdete Bild (Rauschen) nicht wirklich komprimieren kann. Also erst komprimieren und dann verschlüsseln.
Nexus schrieb:
std::vector<unsigned char> Source; const char* PixelArray = reinterpret_cast<const char*>(&Source[0]);
Source[0] darf man natürlich nur aufrufen, falls Source.size()>0 gilt.
-
Nexus:
Du könntest natürlich auch das PNG von SFML lesen und schreiben lassen, schliesslich bietet es diese Funktionalität (sf::Image::LoadFromFile() und sf::Image::SaveToFile()). Um das Bild unkenntlich zu machen, könntest du vor dem Speichern eine Art Verschlüsselung darüber laufen lassen. Dafür modifizierst du die einzelnen Pixel im sf::Image. Nach dem Laden machst du das wieder rückgängig. Nur so eine Idee...
Währe eine gute Idee. Nur will ich noch ein Editor für das Game machen und dort muss ich die Bilder unkenntlich machen. Nichts gegen deine Idee, aber ich finde es auch estetisch schöner wenn die Bilder alle in ein File gepackt werden.
Bis jetzt habe ich mit Vectoren nicht soviel am Hut!
Wieso muss ich erst abfragen, ob ein Vector nicht null ist befor ich ihn aufrufe?Ich Danke euch für Eure hilfe, jedoch funktioniert das ganze nicht. Ich weiss nicht wass ich falsch mache.
Mein Code sieht so aus:FromFilePNG.hpp
#ifndef FROMFILEPNG_HPP_INCLUDED #define FROMFILEPNG_HPP_INCLUDED #include <SFML/Graphics.hpp> #include ".\LodePNG\lodepng.h" #include <iostream> using namespace std; class C_PNGFromFile { private://members for LodePNG vector<unsigned char>m_buffer, m_image; private://members for GetPicture const char* m_image_c; size_t m_size; sf::Image m_Picture; public://Public Member-Functions void LoadPNG(const char* filename); sf::Image& GetPicture(); }; #endif // FROMFILEPNG_HPP_INCLUDED
FromFilePNG.cpp
#include "FromFilePNG.hpp" //Lode PNG with LodePNG and Decode void C_PNGFromFile::LoadPNG(const char* filename) { //Lode Image from png-File, and given filename LodePNG::loadFile(m_buffer, filename); LodePNG::Decoder decoder; //Decode the Image in 32bit decoder.decode(m_image, m_buffer); } //Loade the Picture with SFML and give it back sf::Image& C_PNGFromFile::GetPicture() { //Cast in char-Vector vector<char> Dest(m_image.begin(), m_image.end()); if(m_image.size() > 0) { //copie in const char* m_image_c = &Dest[0]; //Calculate Size in Byte's m_size = (sizeof(char)/strlen(m_image_c)); } cout<<"Image: "<<m_image_c<<endl; //Lode File from Memory with SFML, and check if(false == m_Picture.LoadFromMemory(m_image_c, m_size)); { cout<<"Error: Bild konnte nicht geladen werden."<<endl; } //return the Image return m_Picture; }
In dem Shell-Feister kommt die Ausgabe:
Image:
Failed to load image from memory. Reason : unknown image Type
Error: Bild konnte nicht geladen werden.Als Ausgabe auf den Bildschrim sehe ich nur ein weisses Rechteck, anstadt ein Bild. Die Decodierung müsste stimmen. Entweder mach ich etwas mit dem casten falsch, oder der zweite Parameter von
"LoadFromMemory(const char* Data, size_t SizeInBytes)" ist nicht richtig. In der Doku von SFML steht, SizeInBytes : Size of the data to load, in bytes. Ich weiss nicht genau was sie damit meinen.Wie seht ihr dass?
-
m_size = (sizeof(char)/strlen(m_image_c));
Rechne mal nach...
-
m_size = ((strlen(m_image_c)) / (sizeof(char)));
Meintest du so?
Funktioniert immernoch nicht.
-
Nein, das ist natürlich immer noch falsch - nicht nur der Operator!
Wenn du schon m_image.size() hast, warum versuchst du dann nochmal die Länge zu berechnen??? (du weißt schon, wie strlen() funktioniert, oder?)
P.S. Wofür brauchst du überhaupt die Kopie von m_image (Dest)?
-
du weißt schon, wie strlen() funktioniert, oder?
ja, strlen() giebt die länge an zeichen aus. Hatte ein kleinen blackout.
P.S. Wofür brauchst du überhaupt die Kopie von m_image (Dest)?
Dies wahr mein uhrsprüngliches Problem, wofür ich diesen Beitrag geschrieben habe. ich muste ein "vector<unsigned char>" in ein "const char*" casten. Und so geht es. Allerdings funktioniert das ganze Forhaben nicht, wie du siehst aus Eigenverschulden. Ich hoffe zumindest dass es schlussentlich nur eigenverschulden sind und nicht, dass das ganze überhauptnicht geht.
Ich habe es jetzt so gemacht:
//Cast in char-Vector vector<char> Dest(m_image.begin(), m_image.end()); if(Dest.size() > 0) { //copie in const char* m_image_c = &Dest[0]; //Calculate Size in Byte's m_size = Dest.size(); }
sollte eigentlich funktionieren. oder?
-
Ja, sollte jetzt so funktionieren.
Und wenn du jetzt gleich noch 'm_image' statt 'Dest' benutzt, dann ist es auch noch performant (so wie Nexus schon geschrieben hatte):const char *image_c = reinterpret_cast<const char*>(&m_image[0]); size_t size = m_image.size(); m_Picture.LoadFromMemory(image_c, size);
So benötigst du dann auch nicht die unnötigen Member-Variablen 'm_iamge_c' und 'm_size'.
-
Danke! Danke für eure Hilfe!
Ich habs jetzt so gemachd:
if(m_image.size() > 0) { //Cast from "vector<unsigned char>" to "const char*" m_image_c = reinterpret_cast<const char*>(&m_image[0]); //Get size in Byte's m_size = m_image.size(); } cout<<"Size: "<<m_size<<endl; //Lode File from Memory with SFML, and check if(false == m_Picture.LoadFromMemory(m_image_c, m_size)); { cout<<"Error: Bild konnte nicht geladen werden."<<endl; } //return the Image return m_Picture;
Alllerdings Funktioniert das ganze nicht. Als Ausgabe im Shell-Feister kriege ich:
Size: 1228800
Failed to load image from memory. Reason : Image not of any known type, or corrupt
Error: Bild konnte nicht geladen werden.Weiss halt nicht an wass es liegen könnte. Ich gehe mal in einem SFML-Forum nachfragen. Wenn ihr eine Idee habt, nur her damit, bin um jede Hilfe froh.
-
Ich möchte mich nochmals für die Hilfe bedanken!
Ich habs jetzt geschaft.
Hier ein link http://www.sfml-dev.org/forum/viewtopic.php?t=2045 zu der lösung, fals jemand intresse daran hat.mfg Lumo!!