[Résolu](script) Sauvegarder une image en png avec ruby.
Auteur
Message
valer
Va-nu-pieds Lv.4
Age : 36 Inscrit le : 27/10/2009 Messages : 56
Sujet: [Résolu](script) Sauvegarder une image en png avec ruby. Mer 9 Déc 2009 - 22:22
Bonjour, je suis en train de réaliser un script qui a besoin de sauvegarder une image sur le disque dur. Mais, je n'ai pas trouvé comment faire pour enregistrer l'image en .png.
Est-ce que quelqu'un sait comment faire?
EDIT : S'il n'y a pas de fonctions compilées pour le faire, alors ce n'est même pas la peine de le faire en ruby. Dans ce cas, je contournerai le problème.
Ce que je pourrai faire par contre, c'est envoyé les caractéristiques de l'image à une application compilée pour quelle me génère l'image et me la sauvegarde en png. Mais là, je n'ai pas trouvé de librairies pour lire les png. (SDL_Image n'a même pas lu les png :snif). C'est pas mal : d'un coté, je ne peux pas sauvegarder les PNG, et de l'autre, je ne peux lire les PNG. Y'a de quoi devenir fou!
Soit j'ai deux solutions : je trouve une librairie de C ou C++ qui lit les PNG mais apparement, je suis trop bête pour la trouver. Soit, je trouve une librairie sous Ruby qui permet d'enregistrer l'image en PNG.
Dernière édition par valer le Sam 19 Déc 2009 - 23:12, édité 2 fois
Zangther
Maître des Duels
Age : 32 Inscrit le : 29/07/2009 Messages : 7841
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mer 9 Déc 2009 - 22:27
Ce sont tous deux des scripts de sauvegarde où ladite sauvegarde contient un screen.
Bonne chance pour ta recherche ^^
valer
Va-nu-pieds Lv.4
Age : 36 Inscrit le : 27/10/2009 Messages : 56
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mer 9 Déc 2009 - 22:34
Merci, je n'y avais pas pensé. Je vais chercher dedans, et si je trouve, je vous préviendrai.
EDIT: Merci Zangther pour les scripts, j'ai trouvé comment ils sauvegardent les images. Mais, je veux les sauvegarder dans le format .png.
Arty'
Age : 134 Inscrit le : 14/04/2009 Messages : 1321
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mar 15 Déc 2009 - 18:29
Ya un truc qui m'échappe... Pourquoi cette obsession de vouloir l'enregistrer en png? Daccord, le JPEG ne conserve pas la qualité, mais png n'est pas le seul formtat à conserver la qualité: par exemple, le bitmap.
Arty
Zangther
Maître des Duels
Age : 32 Inscrit le : 29/07/2009 Messages : 7841
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mar 15 Déc 2009 - 18:36
Bah, toutes les images de base de RPG maker sont en PNG...
Mais la question qu'il semble poser est comment la récupérer sous forme d'image.
Matsuo Kaito
Age : 33 Inscrit le : 27/06/2008 Messages : 10881
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mar 15 Déc 2009 - 18:45
Je traduis et complète : RmVx ne sait pas gérer les .bmp ... Seulement les .jpg / .png, voire .gif en insèrant l'un ou l'autre script. Mais si je ne m'abuse, le bmp, certainement pas UwU
Raitosan
† Fondateur du forum †
Age : 31 Inscrit le : 09/02/2008 Messages : 1974
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mer 16 Déc 2009 - 7:38
Les gros problème des BMP, réside dans leurs taille. En effet, on obtient une bonne qualité d'image, mais c'est parceque l'image n'est pas compresser, et de ce fait, il ne faut pas qu'un jeu mette trop de temps à charger une image. Il faut que ce soit le plus rapide possible, ce qui explique que RPG Maker préfère les .png et les .jpg . Entre les deux, je te conseil le .png qui gère la transparence, et qui garde une belle qualité d'image, c'est d'ailleur ce format d'image que j'utilise pour mon jeu
Arty'
Age : 134 Inscrit le : 14/04/2009 Messages : 1321
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Mer 16 Déc 2009 - 10:22
Ah, euh oui, c'est pas totalement faux. Enfin, c'est entièrement juste.
Je n'avais pas penser à la compatibilité... Auatnt dire que le .png reste VRAMENT le format le plus adapté.
Arty
valer
Va-nu-pieds Lv.4
Age : 36 Inscrit le : 27/10/2009 Messages : 56
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby. Sam 19 Déc 2009 - 23:11
C'est vrai le bmp est totalement inadapté: Par exemple, le format 24 bits pour un personnage prend 24*32*32 bits de place mémoire soit 6 KO. Et en plus, il ne gère pas les effets de transparence.
Le gif, c'est un peu pourri. Certes , il gère les effets de transparence mais il n'est codé que sur 8 bits si ma mémoire est bonne. Et en plus, il est sous licence.
Je préfère le png comme l'a dit Raito, parce qu'il gère la transparence. Et en plus, si je me trompe pas, il compresse l'image sans perte contrairement au jpeg.
Pour résumer, ce problème : j'ai crée une application qui génère cette image en png. Puis, je l'importe depuis mon code ruby dans le jeu. Pour l'histoire que je n'arrivais pas à ouvrir mon fichier en png depuis mon programme en C++, ce n'était qu'une histoire de DLL.
Du coup, j'envoie des instructions depuis ruby sur mon programme en C++. Puis mon programme les interprète , et enregistre l'image sur l'emplacement de l'image du personnage. Du coup, je récupère l'image dans mon jeu.
EDIT: Voici une solution:
Spoiler:
Code ruby:
Code:
################################################################################ # script de gestion des apparences # ################################################################################ class Game_Apparence attr_accessor:sex attr_reader:name attr_accessor:nb attr_reader:color def initialize(name,sex=0,nb=0,r=255,g=255,b=255,a=255) @name=name @color=Color.new(r,g,b,a) @sex=sex%2 @nb=nb end def existe?(partie) if @sex==0 path="femme/" else path="homme/" end path2="./Apparences/fichier.exe " + "Apparences/Images/Personnages/" + path + @name + "/" + (@nb.to_s) + "/0.png" if system(path2)==false return false else return true end end def suiv @nb+=1 if (existe?(self)==false) @nb-=1 end return self end def prec @nb-=1 if (existe?(self)==false) @nb+=1 end return self end def switch_sex @sex=1-@sex end def change_color(color) @color=color end def save(myfile) temp= (@color.red.to_i.to_s) temp+="\n" temp+= (@color.green.to_i.to_s) temp+="\n" temp+= (@color.blue.to_i.to_s) temp+="\n" temp+= (@color.alpha.to_i.to_s) temp+="\n" if @sex==0 temp+= "femme/" else temp+="homme/" end temp+= (@name) temp+="\n" temp+= (@nb.to_s) temp+="\n" myfile.write(temp) end end class Game_Perso def initialize(perso,sex=0) @perso=perso @data=[] @sex=sex%2 @maj=false end def del(value) @maj=false for i in 0..@data.size-1 if @data[i].name==value for j in i+1..@data.size-1 @data[j-1]=@data[j] end @data[j]=nil end end return self end def [](value) @maj=false for i in 0..@data.size-1 if @data[i].name==value return @data[i] end end @data[@data.size]=Game_Apparence.new(value,@sex)
return @data[@data.size-1] end def switch_sex @sex=1-@sex return self end def refresh if @maj==false myfile=File.open("Apparences/ordres.cfg",'w') temp=(@data.size.to_s) + "\n" myfile.write(temp) for i in 0..@data.size-1 @data[i].save(myfile) end myfile.close() temp="./Apparences/generateur.exe Graphics/Characters/" + @perso.character_name + ".png " + "/Images/Personnages/" system(temp) @maj=true end end end
Code C++/C headers Element.h
Code:
#ifndef ELEMENT_H_INCLUDED #define ELEMENT_H_INCLUDED class Element { friend bool file_exist(std::string & s); public: //Constructeur Element(void); //Chargement des paramètres, et de l'image de l'élément. bool charger(ifstream &,string& path,Couleur & couleur); //Colle l'élément sur une surface. SDL_Surface * coller(SDL_Surface *); //Détruit l'élément ~Element(void); //Retourne le niveau de l'élément unsigned int retourne_niveau(void); private: void definirPixel(SDL_Surface * surface,int x, int y, Uint32 pixel); Uint32 Element::obtenirPixel(SDL_Surface * surface,int x, int y); bool blit(SDL_Surface * s); //Change la couleur de l'élément. bool colorier(Couleur &); //Stocke le niveau d'affichage de l'élément unsigned int niveau; //Stocke l'image de l'élément SDL_Surface * surface; //Stocke le fait si l'élément est propriétaire de la surface bool owner; }; #endif // ELEMENT_H_INCLUDED
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <SDL/SDL.h> #include <SDL_image.h> using namespace std; #include "couleur.h" #include "Element.h" ///On définit un pixel void Couleur::definirPixel(SDL_Surface * surface,int x, int y, Uint32 pixel) { /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur de l'image : 8, 16, 24 ou 32 bits.*/ int nbOctetsParPixel = surface->format->BytesPerPixel; /*Ici p est l'adresse du pixel que l'on veut modifier*/ /*surface->pixels contient l'adresse du premier pixel de l'image*/ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/ switch(nbOctetsParPixel) { case 1: *p = pixel; break;
case 4: *(Uint32 *)p = pixel; break; } } ///On récupère la valeur d'un pixel Uint32 Couleur::obtenirPixel(SDL_Surface * surface,int x, int y) { /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur de l'image : 8, 16, 24 ou 32 bits.*/ int nbOctetsParPixel = surface->format->BytesPerPixel; /* Ici p est l'adresse du pixel que l'on veut connaitre */ /*surface->pixels contient l'adresse du premier pixel de l'image*/ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/ switch(nbOctetsParPixel) { case 1: return *p;
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <SDL/SDL.h> #include <SDL_image.h> using namespace std; #include "utile.h" #include "couleur.h" #include "Element.h" ///Constructeur void Element::definirPixel(SDL_Surface * surface,int x, int y, Uint32 pixel) { /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur de l'image : 8, 16, 24 ou 32 bits.*/ int nbOctetsParPixel = surface->format->BytesPerPixel; /*Ici p est l'adresse du pixel que l'on veut modifier*/ /*surface->pixels contient l'adresse du premier pixel de l'image*/ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/ switch(nbOctetsParPixel) { case 1: *p = pixel; break;
case 4: *(Uint32 *)p = pixel; break; } } ///On récupère la valeur d'un pixel Uint32 Element::obtenirPixel(SDL_Surface * surface,int x, int y) { /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur de l'image : 8, 16, 24 ou 32 bits.*/ int nbOctetsParPixel = surface->format->BytesPerPixel; /* Ici p est l'adresse du pixel que l'on veut connaitre */ /*surface->pixels contient l'adresse du premier pixel de l'image*/ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/ switch(nbOctetsParPixel) { case 1: return *p;
/*Ne devrait pas arriver, mais évite les erreurs*/ default: return 0; } } ///On change la couleur d'une surface bool Element::blit(SDL_Surface * s) { if (surface!=NULL) { for(int i=0;i<s->w;i++) { for(int j=0;j<s->h;j++) {
/*Pour récupérer le code couleur d'un pixel*/ Uint32 pixel=obtenirPixel(s,i,j); Uint32 pixel2=obtenirPixel(surface,i,j); Uint8 r1,g1,b1,a1; SDL_GetRGBA(pixel, s->format, &r1, &g1, &b1, &a1); Uint8 r0,g0,b0,a0; SDL_GetRGBA(pixel2, surface->format, &r0, &g0, &b0, &a0); r1=(r0*a0)/255.0 + ((255-a0)*a1*r1)/(255.0*255.0); g1=(g0*a0)/255.0 + ((255-a0)*a1*g1)/(255.0*255.0); b1=(b0*a0)/255.0 + ((255-a0)*a1*b1)/(255.0*255.0); if (a1<a0) { a1=a0; } pixel=SDL_MapRGBA(surface->format, r1, g1, b1, a1); /*Et pour changer la valeur d'un pixel*/ definirPixel(s,i,j,pixel); } cerr <<"\n"; } } else { cerr << "Impossible de recolorier la surface\nCause : La surface est vide\n"; return false;
} return true; } Element::Element(void) { //Mise des pointeurs à NULL pour détecter s'ils ont étés alloués! surface=NULL; owner=true; //Mise du niveau à 0. niveau=0; } ///Chargement de l'élément bool Element::charger(ifstream & file,string& path,Couleur& couleur) { ///Chargement des paramètres { //Si le fichier n'a pas été ouvert! if (!file) { return false; } //Chargement du niveau file >> niveau; } ///Chargement de l'image { //Test si le fichier existe if (!file_exist(path)) { cerr <<"Erreur: Le programme n'arrive pas à lire:" <<path<<"\n"; return false; } //Charge la Surface surface=IMG_Load(path.c_str()); //Teste si la surface a été chargée. if (surface==NULL) { cerr << SDL_GetError() << "\n"; return false; } } ///Coloriage de l'image { return colorier(couleur); } } ///Collage de l'élément sur une surface SDL_Surface * Element::coller(SDL_Surface * s) { ///Teste si la surface est non vide { if (s==NULL) { if (surface!=NULL) { s=SDL_CreateRGBSurface(SDL_HWSURFACE||SDL_SRCALPHA, surface->w, surface->h,surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, 0, 0, 0,0)); }
} } if (surface==NULL) return s; ///Colle l'élément sur la surface s { SDL_Rect p; p.x=0; p.y=0; blit(s); } return s; } ///Destructeur Element::~Element(void) { ///Libération de la surface { if (surface!=NULL && owner) SDL_FreeSurface(surface); }
} ///Permet de colorier l'élément bool Element::colorier(Couleur & couleur) { if (!surface) { return false; } return couleur.colorier(surface); } ///Retourne le niveau unsigned int Element::retourne_niveau(void) { return niveau; }
Contenu sponsorisé
Sujet: Re: [Résolu](script) Sauvegarder une image en png avec ruby.
[Résolu](script) Sauvegarder une image en png avec ruby.