Récupérer une image croppée via un formulaire

Comment faire?

a marqué ce sujet comme résolu.

Bonjour ! J'ai installé le plugin Jquery CropIt , qui permet de redimensionner et cropper les images dans une fenetre de prévisualisation. Le plugin se trouve ici : http://scottcheng.github.io/cropit/

Bref , je souhaite enregistrer cette image croppée et redimensionnée seulement je ne sais pas exactement comment faire.Tout d'abord mon formulaire d'upload fonctionne trés bien sans ce plugin.

Voici mon entité image :

 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
  {
    $this->file = $file;


    if (null !== $this->url) {
      $this->tempFilename = $this->url;

      $this->url = null;
      $this->alt = null;
    }
  }

  /**
   * @ORM\PrePersist()
   * @ORM\PreUpdate()
   */
  public function preUpload()
  {

    if (null === $this->file) {
      return;
    }


    $this->url = $this->file->guessExtension();


    $this->alt = $this->file->getClientOriginalName();
  }

  /**
   * @ORM\PostPersist()
   * @ORM\PostUpdate()
   */
  public function upload()
  {

    if (null === $this->file) {
      return;
    }


    if (null !== $this->tempFilename) {
      $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->tempFilename;
      if (file_exists($oldFile)) {
        unlink($oldFile);
      }
    }


    $this->file->move(
      $this->getUploadRootDir(), // Le répertoire de destination
      $this->id.'.'.$this->url   // Le nom du fichier à créer, ici « id.extension »
    );
  }

  /**
   * @ORM\PreRemove()
   */
  public function preRemoveUpload()
  {
    $this->tempFilename = $this->getUploadRootDir().'/'.$this->id.'.'.$this->url;
  }

  /**
   * @ORM\PostRemove()
   */
  public function removeUpload()
  {
    if (file_exists($this->tempFilename)) {
      // On supprime le fichier
      unlink($this->tempFilename);
    }
  }

Et voici la partie du formulaire qui permet d'uploader l'image :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    {{ form_label(form.image, 'Image', {'label_attr': {'class': 'col-sm-3 control-label'}})}}
      <div class="image-cropper">
          <!-- This is where the preview image is displayed -->
          <div class="row">
            <div class="col-sm-offset-2">

                <div class="col-sm-4">
                  {{ form_widget(form.image) }}
                </div>
            <div class="cropit-image-preview"></div>

          <!-- This range input controls zoom -->
          <!-- You can add additional elements here, e.g. the image icons -->
            <div class="col-sm-offset-4 col-sm-4">
                <input type="range" class="cropit-image-zoom-input" />
            </div>

            {{ form_errors(form.image) }}
            <div class="col-sm-4">
            {{ form_widget(form.image, {'attr': {'class': 'cropit-image-input'}}) }}
            </div>
              <div class="select-image-btn">Select new image</div>
      </div>
    </div>

le code Jquery qui va avec :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/javascript" src="{{ asset('js/cropit-master/dist/jquery.cropit.js') }}"></script>

<script>
$(function() {
$('.image-cropper').cropit({imageState: {src: { 'http://lorempixel.com/500/400/' },
          },
  });
// When user clicks select image button,
// open select file dialog programmatically
  $('.select-image-btn').click(function() {
   $('.cropit-image-input').click();
});

  $('#oah_newsbundle_article_save').click(function() {
        // Move cropped image data to hidden input
        var imageData = $('.image-cropper').cropit('export');
        $('#oah_newsbundle_article_image_file').val(imageData);
      };
   });
</script>

Je m'explique sur celui-ci (je n'y connais pas grand chose encore en Jquery/Js ). Le plugin dispose d'une option "export" qui permet à priori d'exporter la valeur de la nouvelle image en data URI. Dans le tuto sur ce plugin , ils utilisent cette variable imageData soit pour l'afficher directement via un

1
window.open(imageData);

Soit pour enregistrer cette valeur dans un Hidden Input du formulaire. Du coup au lieu de créer cet input , j'ai essayé de modifier la valeur de l'input de mon image pour enregistrer la valeur de l'image redimensionnée.Ca ne marche pas… Du coup quelqu'un pourrait me donner des pistes sur comment persister cette valeur et non l'image d'origine? Merci

Salut !

De ce que je comprends, il te faudrait un champ <input type="file" /> "bidon" pour pouvoir sélectionner le fichier et le fournir au plug-in. Ensuite, il faudra un autre champ caché qui récupérera l'image découpée (celui-ci sera donc le "vrai" champ), apparemment il y a des solutions existantes directement avec les données data-URI – le "vrai" champ sera du coup un simple <input type="hidden" />.

Peut-être qu'un pro du JavaScript pourra te proposer une solution avec les objets de type Image de JavaScript et un champ réellement de type file, mais là, c'est plus à ma portée  ^^

+0 -0

Bonjour. Je me suis connecté avec le mauvais compte mais la question est de moi. Du coup c'est exactement ça, sauf que de une je ne sais pas comment récupérer la valeur d'un champ hidden à la place de mon "input type=file". D'où la tentative de remplacer mon vrai input file par la valeur de imageData

Dans ton ***Type, tu mets un champ pour les fichiers, non-mappé, et un champ caché que tu traites comme n'importe quel autre champ dans ton entité.

1
2
3
4
<?php
//…
->add('fichier', 'file', array('mapped' => false))
->add('file', 'hidden')

Il te faudra en revanche mettre l'attribut file de ton entité Image en privé, et définir setFile et getFile. Ce dernier devrait simplement retourner $this->file, mais le setter va utiliser le traitement montré sur StackOverflow pour récupérer l'image depuis le data-URI.

+0 -0

Bonsoir , ça se passe assez mal…

J'ai donc modifier mon ImageType comme ceci:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class ImageType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('Image', 'file', array('mapped' => false),array(
                'attr' => array('class' => 'cropit-image-input')))
            ->add('file', 'hidden', array('attr' => array('class' => 'hidden-image-data')))

        ;
    }

en ajoutant donc un champs caché avec la classe "hidden-image-data"

Le code Jquery est donc le suivant :

1
2
3
4
5
6
7
$(function() {
$('form').submit(function() {

        var imageData = $('.image-cropper').cropit('export');
        $('.hidden-image-data').val(imageData);
      };
   });

Mon formulaire d'upload d'image ne change pas mais je le remets :

 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
<div class="form-group">
    {{ form_label(form.image, 'Image', {'label_attr': {'class': 'col-sm-3 control-label'}})}}
      <div class="image-cropper">
          <!-- This is where the preview image is displayed -->
          <div class="row">
            <div class="col-sm-offset-2">

                <div class="col-sm-4">
                  {{ form_widget(form.image) }}
                </div>
          <div class="cropit-image-preview-container">
            <div class="cropit-image-preview"></div>
          </div>

          <!-- This range input controls zoom -->
          <!-- You can add additional elements here, e.g. the image icons -->
            <div class="col-sm-offset-4 col-sm-4">
                <input type="range" class="cropit-image-zoom-input" />
            </div>

            {{ form_errors(form.image) }}
            <div class="col-sm-4">
            {{ form_widget(form.image, {'attr': {'class': 'cropit-image-input'}}) }}
            </div>
              <div class="select-image-btn">Select new image</div>
      </div>

et mon entité Image ( et c'est la ou je suis vraiment perdu ) devient :

 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
 public function getFile()
  {
    return $this->file;
  }

  public function setFile(UploadedFile $file = null)
  {
    $decoded = urldecode($file);
    $exp = explode(';', $decoded);
    $exp = explode(':', $exp[0]);
    $data = array_pop($exp);
    $this->file = $data;


    if (null !== $this->url) {
      $this->tempFilename = $this->url;

      $this->url = null;
      $this->alt = null;
    }
  }

  /**
   * @ORM\PrePersist()
   * @ORM\PreUpdate()
   */
  public function preUpload()
  {

    if (null === $this->file) {
      return;
    }


    $this->url = $this->file->guessExtension();


    $this->alt = $this->file->getClientOriginalName();
  }

  /**
   * @ORM\PostPersist()
   * @ORM\PostUpdate()
   */
  public function upload()
  {

    if (null === $this->file) {
      return;
    }


    if (null !== $this->tempFilename) {
      $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->tempFilename;
      if (file_exists($oldFile)) {
        unlink($oldFile);
      }
    }


    $this->file->move(
      $this->getUploadRootDir(),
      $this->id.'.'.$this->url   
    );
  }
1
J'ai l'erreur suivante :
1
2
3
An exception occurred while executing 'INSERT INTO image (url, alt) VALUES (?, ?)' with params [null, null]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Le champ 'url' ne peut être vide (null)

```

Je ne comprends pas vraiment comment récupérer la valeur de mon champs caché. Normalement la je le récupere puisque je recupere le champs File? J'aurais besoin d'un coup de main svp … Merci

Il manque la création d'une réelle image depuis les données, je pense que tu peux tenter avec la fonction imagecreatefromstring(), sachant que la chaîne à passer en paramètre est ta variable $data dans ton setFile(), je dirais.
Mais ça, c'est si tu souhaites faire de la validation sur ton image ("poids", dimensions, ratio, etc.).

Sinon, il y a ce complément du lien que j'avais fourni avant,

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte