Bonjour,
Je fais actuellement un concours de photos et le problème qui est d'après mes multiples recherche assez connu des webmaster qui manipulent des photos : il faut donc redimensionner les photos côté client avant de les envoyer sur le serveur.
Sachant qu'il est impossible de faire ça en javascript, j'ai utilisé flash mais je ne suis vraiment pas initié a Flash.
Pour l'instant j'ai fais un petit script Flash qui permet :
- de demander a l'utilisateur une photo (filereference.browse() )
- Puis de transformer cette photo en displayObject pour la redimensionner et avoir la taille (height et width) du bitmapData qui va etre créé
- Création d'un bitmapData avec les height et width que j'ai eu précédemment
- methode draw sur ce nouveau bitmapdata avec en argument le displayObject redimentionné
- Comme apparement draw ( ) m'a dessiné le displayObject *tel qu'elle*, pas redimensionné, j'applique une matrice de redimensionnement.
- J'encode ensuite avec getPixel() une chaine qui ou chaque pixel sera encodé en hexadecimal, la chaîne ressemblera a "0f0e872f0a8e0ff775885a4b5 etc....."
- Envoi avec URLLoader de cette chaine a mon serveur PHP qui générera un jpg en décodant la chaine
Il y a 3 problèmes majeurs :
- La qualité de l'image résultante est vraiment médiocre (même en mettant 100 pour la qualité du jpg créé en PHP, ce doit etre la matrice de draw() qui fait ca ..)
- Le temps d'envoi est très long pour une image de taille max 600*600
- Il n'y a pas de barre de progression sur flash pour voir le nombre d'octets envoyé sur le total pour les URLLoader (il y en mais c'est pour les octets recu pas envoyés)
Sans compter la complexité et le temps fou que ça m'a mis pour concevoir, au moins 2 semaine(mais jconnaissais rien a flash avant quand meme
)
Bref est-ce qu'il y aurai un moyen, avec Flash d'encoder un jpg directement dans flash(reduction du temps d'envoi), d'avoir une progressBar qui gère l'envoi des octets, et d'avoir une image de meilleur qualité ..
Et voici le code PHP chargé de la reconstitution :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 import flash.geom.Matrix; import flash.events.Event; import flash.external.*; // btn_upload est un bouton et statut est un champs dynamique var f_statut = new TextFormat(); var fileRef:FileReference= new FileReference(); var reponse:String = ""; var net:URLLoader = new URLLoader(); btn_upload.addEventListener(MouseEvent.MOUSE_DOWN, onDown); function onDown(evt:MouseEvent):void { fileRef.browse([new FileFilter("Images", "*.jpg;*.png")]); fileRef.addEventListener(Event.SELECT, onSelected); } function onSelected(evt:Event):void { ExternalInterface.call("loadStart","null"); // Appel d'une fonction javascript pour cacher // le bouton enregistrer (pour pas que les gens clique dessus pdt le chargement fileRef.addEventListener(Event.COMPLETE, onLoaded); fileRef.load(); fileRef.removeEventListener(Event.SELECT, onSelected); f_statut.color = 0x222222; f_statut.italic = true ; f_statut.font = "Tahoma"; statut.defaultTextFormat = f_statut; statut.text = 'Chargement de l\'image..' ; removeChild(btn_upload); } function onLoaded(evt:Event):void{ // Elemenrts d'affichage var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE , completeHandler ); loader.loadBytes(evt.target.data); fileRef.removeEventListener(Event.COMPLETE, onLoaded); } function completeHandler(event:Event):void { statut.text = 'Ajustement de l\'image (peut durer quelques minutes)..'; var image:DisplayObject = event.currentTarget.loader.content; var hmax = 600 ; var wmax = 600; var h_orig = image.height ; var w_orig = image.width ; var coefre:Number = 1 ; if(image.height > hmax) { coefre = hmax / image.height ; image.height = hmax ; // Coef de reduc < 1 image.scaleX = coefre ; // Coef de reduc < 1 } if(w_orig * coefre > wmax ) { var coefre2 = wmax / (w_orig * coefre) ; image.scaleY = coefre2 * coefre ; image.scaleX = coefre2 * coefre ; } var coefinale = image.height / h_orig ; // Image redimenssionné, on crée un bitemapData a partir du displayObject var bitmapData:BitmapData = new BitmapData( image.width, image.height); var matrix:Matrix = new Matrix(); matrix.scale(coefinale ,coefinale); bitmapData.draw(image,matrix, null, null, null, true); var i = 0; var j = 0; var head_r = new String("id_cc:"+ root.loaderInfo.parameters.cc+" ,id_mb:"+ root.loaderInfo.parameters.mb+" , h:+"+bitmapData.height+",w:"+bitmapData.width); // (J'envoi avec le "body", une head qui contient quelques infos sur l'image que j'analyse apres avec PHP var body_r = new String(""); // Encodage for(i = 0;i < bitmapData.height; i++) { for(j = 0; j < bitmapData.width; j++) { var str_pixel = bitmapData.getPixel(j, i).toString(16); // Remplissage de 0 while(str_pixel.length < 6) { str_pixel = "0"+str_pixel ; } body_r += str_pixel ; } } statut.text = 'Envoi en cours... (l\'opération peut prendre quelques minutes)' ; trace("len : " +body_r.length+"\n"); trace(body_r) ; var reqinfo:URLRequest = new URLRequest("prive/cimage.php") ; net.dataFormat = URLLoaderDataFormat.TEXT ; reqinfo.method = "POST" ; var variables:URLVariables = new URLVariables(); variables.head = head_r variables.body = body_r; reqinfo.data = variables ; //Changement de couleur du statut (final) f_statut.color = 0x882222; f_statut.bold = true; f_statut.italic = false ; statut.defaultTextFormat = f_statut; net.load(reqinfo); net.addEventListener(Event.COMPLETE, onCompleteUpload); net.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); net.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); } function onCompleteUpload(event:Event): void { // Analyse de la reponse donné par mon script, pour afficher a l'utilisateur si sa photo a bien été enregistrée if(net.data.substr(0,3) == "id:"){ ExternalInterface.call("idf", net.data.substr(3,40)); // Appel d'un autre fonction javascript f_statut.color = 0x228822; statut.defaultTextFormat = f_statut; statut.text = "Image chargée avec succès"; } else if(net.data == "203") statut.text = "Vous n'avez pas les droits pour poster sous l'identité de quelqu'un d'autre. Code d'erreur : 203"; else statut.text = "Impossible de charger l'image. Code d'erreur : "+net.data+". Contactez l'administrateur."; } // Gestion des erreurs function securityErrorHandler(event:SecurityErrorEvent):void { statut.text = "Erreur de sécurité." ; } function ioErrorHandler(event:IOErrorEvent):void { statut.text = "Erreur de chargement : Impossible de se connecter à Internet"; }
Merci d'avance de votre aide
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 <?php /* cimage.php ---------- Analyse l'image en entrée, vérifie la validité des paramètres et reconstitue une image Appelé par un script flash sans recharger la page. En entrée, un tableau POST : head => "cc:#, mb:#, h:#, w: #" // # représente une valeur body => # Une chaine contenant toutes les couleurs de chaque pixel de l'image en hexadecimal sans séparateur Sortie : Un tableau flashvar (foo=bar&var=oo) contenant le code retourné et le message d'erreur en cas d'erreur utilisateur code=#&msg=# Codes d'erreur retournés ------------------------ 001 : Image crée avec succès. 1xx : Erreur d'arguments 100 : l'entete ou le body n'ont pas été envoyé 101 : En tete incorrect (pas un format d'arguments d'URL valide ) 11x : l'head ne contient pas un argument requis 110 : l'ID concours incorrect (non défini ou non int) 111 : ID membre incorrect 112 : hauteur incorect 113 : largeur incorect 12x : Erreur sur le body 120 : strlen(body) n'est pas un ultiple de 6 (6 caractère pr une couleur hexa) 121 : le nombre d'octet de body n'est pas égal a longueur * largeur : il est superieur ; 122 : le body contient un caractere incorect. 2xx : Erreur utilisateur 200 : l'utilisateur n'existe pas. 201 : le concours n'existe pas. 202 : l'utilisateur ne peut plus poster pour ce concours 203 : L'utilisateur n'a pas l'autorisation de poster une image pour qqn d'autre. "id:xxxxx" : correspond a aucune erreur et renvoi en meme temps l'ID de l'image */ define("MAX_HEIGHT", 600); define("MAX_WIDTH", 600); // Declaration que cette page est une pages d'index define("SITE_LOCAL",file_get_contents("../_local.txt")); define("INDEX", 1); require_once((SITE_LOCAL)? "../sql_local.php" : "../sql_distant.php"); require_once("../fonction/utiles.php"); // Fin des déclarations d'index // Declaration du service membre session_start(); if(session()){ require_once('control/start_cmp.php'); } // fin de toute les declarations function out($code) // Je sais cette fonction ne sert a rien mdr { die($code); } if(isset($_POST['head']) && isset($_POST['body']) && !empty($_POST['head']) && !empty($_POST['body'])) { $head = str_replace(" ","",$_POST['head']); if(!substr_count($head, ",")) out(101); $headbrut = explode(",",$head); $args_head = array(); foreach($headbrut as $paire) // Pour chaque argument, dégager la clé et la valeur { if(substr_count($paire,":") != 1) out(101); $cpl = explode(":",$paire); $args_head[$cpl[0]] = abs(floor((int)$cpl[1])); } // Analyse des arguments head if(!array_key_exists("h", $args_head) || $args_head["h"] > MAX_HEIGHT) out(112); if(!array_key_exists("w", $args_head) || $args_head["w"] > MAX_WIDTH) out(113); if(!array_key_exists("id_cc", $args_head)) out(110); else { $ID_cc = mysql_real_escape_string(htmlspecialchars($args_head["id_cc"])); dbGet("SELECT ID FROM concours__ WHERE ID = '$ID_cc'",$sql)or out(201); } if(!array_key_exists("id_mb", $args_head)) out(111); else { if($_MEMBRE['droits']['POST_IMG_FROM_ALL_USERS']) { $ID_mb = mysql_real_escape_string(htmlspecialchars($args_head["id_mb"])); dbGet("SELECT ID FROM membre__ WHERE ID = '$ID_mb'",$sql)or out(200); } else if($args_head["id_mb"] != $_MEMBRE['ID']) out(203); } $body = $_POST['body']; if(strlen($body) % 6 != 0) // Verification que le nb de caractère est bien un multiple de 6 out(120); if(strlen($body) / 6 != $args_head['h'] * $args_head['w']) out(121) ; if(!preg_match("#[a-f1-9]#",$body)) out(122); $image = imagecreatetruecolor($args_head['w'],$args_head['h']); $curseur = 0 ; $cmp = 0 ; for($i = 0; $i < $args_head ['h']; $i++) { for($j = 0; $j < $args_head['w']; $j++) { //echo "Analyse d'un bloc--------------<br/> "; //echo "substr(body, $curseur, ". ($curseur + 6).") <br/>" ; $color = substr($body, $curseur, 6) ; //echo "color : ". $color . "<br/>" ; //echo "red : ". hexdec(substr($color,0,2)) ."<br/>"; $color_id = imagecolorallocate ($image, hexdec(substr($color,0,2)),hexdec(substr($color,2,2)) ,hexdec(substr($color,4,2)) ); imagesetpixel($image, $j,$i, $color_id); $curseur += 6; //echo $curseur . " <br/> "; //echo "------------------------<br/>"; $cmp ++ ; } } mysql_query("INSERT INTO cc__img VALUES('','','{$args_head["id_mb"]}','{$args_head["id_cc"]}','','0',NOW())",$sql)or die(mysql_error()); $id_img = mysql_insert_id($sql) ; header('Content-Type: image/jpeg'); imagejpeg($image, "img_cc/$id_img.jpg",100); imagedestroy($image); out("id:".$id_img); } else out(100) ;![]()
Jerem
Partager