doupacan2098 2015-11-28 15:27
浏览 62
已采纳

Symfony2-Cropit | 如何取回我的裁剪图像?

i'm very disapointed with this plugin.I'm a noob in JS/Jquery but i very need this plugin for my site... So i found cropit here : http://scottcheng.github.io/cropit/

I don't know how to get back my cropped image in my controller and save it... So my form is :

<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 col-sm-8">
              <div class="cropit-image-preview-container">
               <div class="cropit-image-preview"></div>
             </div>
           </div>
         </div> 
                <!-- This range input controls zoom -->
                    <!-- You can add additional elements here, e.g. the image icons -->
          <div class="row">
            <div class="col-sm-offset-4 col-sm-4">
              <input type="range" class="cropit-image-zoom-input" />
            </div>
          </div>
              {{ form_errors(form.image) }}

          <div class="row">    
            <div class="col-sm-4">
              {{ form_widget(form.image) }}
                <div class="select-image-btn">Select new image</div>
                <div class="send_image">Get Cropped image.</div>
            </div>
          </div>
      </div>
</div>

my Jquery code :

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="{{ asset('js/cropit-master/dist/jquery.cropit.js') }}"></script>

<script>
 $(function () {
     $('.select-image-btn').click(function(){
         $('.cropit-image-input').click();
    });


      var z = $('.image-cropper');
      z.cropit({
          exportZoom: 0.5,
          imageBackground: true,
          imageBackgroundBorderWidth: 15
      });
      $('.send_image').click(function() {
            var h =z.cropit('export');
            alert(h);
       });
   });
</script>

my Image.php entity :

     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 = imagecreatefromstring($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);
    }
  }

  public function getUploadDir()
  {
    // On retourne le chemin relatif vers l'image pour un navigateur
    return 'uploads/img';
  }

  protected function getUploadRootDir()
  {
    // On retourne le chemin relatif vers l'image pour notre code PHP
    return __DIR__.'/../../../../web/'.$this->getUploadDir();
  }

  public function getWebPath()
  {
    return $this->getUploadDir().'/'.$this->getId().'.'.$this->getUrl();
  }

I saw lots of posts but nothing is working for me and i don't very understand. So somebody can help and explain to me please? thank you

EDITED : MY FIRST METHOD

my form was with an hidden input to save the base64 data :

 $('form').submit(function() {
        // Move cropped image data to hidden input
        var imageData = $('.image-cropper').cropit('export');
        $('.hidden-image-data').val(imageData);
      };``

and my Imagetype with a file input to load the original image and hidden input to save the base64 image.

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file', 'file', array(
                'attr' => array('class' => 'cropit-image-input')))
            ->add('file', 'hidden', array('attr' => array('class' => 'hidden-image-data')))

        ;
    }

my controller was still the same.

  • 写回答

2条回答 默认 最新

  • dongmaopiao0901 2016-01-29 23:30
    关注

    I have resolved.

    In addition using VichUploaderBundle

    @K-Phoen response has been of great use to direct the solution. VichUploaderBundle & Cropit - Pass base64 to a File instance

    this is my code:

    User.php, this and more VichUploaderBundle setup look here

    namespace Application\Sonata\UserBundle\Entity;
    
    //...
    use Vich\UploaderBundle\Mapping\Annotation as Vich;
    
    /**
     * User
     *
     * ........
     * ........
     * @Vich\Uploadable
     * ........
     * ........
     * 
     */
    class User extends BaseUser {
    
        /**
         * NOTE: This is not a mapped field of entity metadata, just a simple property.
         * 
         * @Vich\UploadableField(mapping="user_avatar", fileNameProperty="avatarName")
         * 
         * @var File
         */
        private $avatar;
    
        /**
         * @ORM\Column(type="string", length=255)
         *
         * @var string
         */
        private $avatarName;
    
        /**
         * @ORM\Column(type="datetime")
         *
         * @var \DateTime
         */
        private $updatedAt;
    
        //....
    
    
        /**
         * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
         * of 'UploadedFile' is injected into this setter to trigger the  update. If this
         * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
         * must be able to accept an instance of 'File' as the bundle will inject one here
         * during Doctrine hydration.
         *
         * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
         */
        public function setAvatar(File $image = null) {
            $this->avatar= $image;
    
            if ($image) {
                // It is required that at least one field changes if you are using doctrine
                // otherwise the event listeners won't be called and the file is lost
                $this->updatedAt = new \DateTime('now');
            }
        }
    
        /**
         * @return File
         */
        public function getAvatar() {
            return $this->avatar;
        }
    
        /**
         * @param string $avatarName
         */
        public function setAvatarName($avatarName) {
            $this->avatarName= $avatarName;
        }
    
        /**
         * @return string
         */
        public function getAvatarName() {
            return $this->avatarName;
        }
    
    }
    

    UserType.php

    namespace AppBundle\Form;
    
    //...
    use Doctrine\Common\Persistence\ObjectManager;
    use AppBundle\Form\DataTransformer\ImageStringToFileTransformer;
    
    class UserType extends AbstractType {
    
        private $manager;
    
        public function __construct(ObjectManager $manager)
        {
            $this->manager = $manager;
        }
    
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder                
                ->add('avatar', 'hidden', [
                    'attr' => [
                        'class' => 'hidden-image-data'
                    ]
                ])
                ->add('imagedata', 'file', [
                    'mapped' => false,
                    'required' => false,
                    'attr' => [
                        'class' => 'cropit-image-input'
                    ]
                ])
                //...
                ;
    
            $builder->get('avatar')
                ->addModelTransformer(new ImageStringToFileTransformer($this->manager));
        }
    
        //...
    
    }
    

    ImageStringToFileTransformer.php, here the magic is done, we convert base64 string to UploadedFile

    namespace AppBundle\Form\DataTransformer;
    
    use Symfony\Component\Form\DataTransformerInterface;
    use Doctrine\Common\Persistence\ObjectManager;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    /**
     * Description of ImageStringToFileTransformer
     *
     * @author Juanjo García
     */
    class ImageStringToFileTransformer implements DataTransformerInterface {
    
        private $manager;
    
        public function __construct(ObjectManager $manager) {
            $this->manager = $manager;
        }
    
        /**
         * Transforms a string (base64) to an object (File).
         *
         * @param  string $imageString
         * @return File|null
         * @throws TransformationFailedException if no object (File)
         */
        public function reverseTransform($imageString) {
    
            // no base64? It's optional, so that's ok       
            if (!$imageString) {
                return;
            }
    
            preg_match('/data:([^;]*);base64,(.*)/', $imageString, $matches);
    
            $mimeType = $matches[1];
            $imagenDecodificada = base64_decode($matches[2]);
            $filePath = sys_get_temp_dir() . "/" . uniqid() . '.png';
            file_put_contents($filePath, $imagenDecodificada);
    
            $file = new UploadedFile($filePath, "user.png", $mimeType, null, null, true);
    
            if (null === $file) {
                // causes a validation error
                // this message is not shown to the user
                // see the invalid_message option
                throw new TransformationFailedException(sprintf(
                     'An issue with number "%s" does not exist!', $imageString
                ));
            }
    
            return $file;
        }
    
        /**
         * Transforms an object (File) to a string (base64).
         *
         * @param  File|null $file
         * @return string
         */
        public function transform($file) {
            return '';
        }
    
    }
    

    services.yml

    services:
    
        # datatransformer before saving to image
        app.form.type.user:
            class: AppBundle\Form\UserType
            arguments: 
                entityManager: "@doctrine.orm.entity_manager"
            tags:
                - 
                    name: form.type
    

    in my Twig, my_form.html.twig

    <script src="{{ asset('jquery.js') }}"></script>
    <script src="{{ asset('jquery.cropit.js') }}"></script>
    <script src="{{ asset('jquery.custom.js') }}"></script>
    
    {% form_theme form with ['AppBundle:Forms:vich_cropit_fields.html.twig'] %}
    
    {{ form_start(form, {'action': path('the_path'), 'method': 'POST', 'multipart': true, 'attr': {'class': 'the_class', 'role': 'form'} }) }}
        <div class="image-editor">
            <div class="cropit-image-preview-container">
                <div class="cropit-image-preview"></div>
            </div>
            {{ form_widget(form.avatar) }}
            {{ form_widget(form.imagedata) }} 
            <div class="image-size-label">
            Resize image
            </div>
            <input type="range" class="cropit-image-zoom-input">
            {% if app.user.avatarName %}
                <img src="{{ vich_uploader_asset(app.user, 'avatar') }}" id="current-avatar" class="hide" />
            {% endif %}
        </div>   
    
        {{ form_rest(form) }}       
    
        <button type="submit" name="submit">Save</button>  
    
    {{ form_end(form) }}
    

    init Cropit, jquery.custom.js

    (function ($) {
    
        $('.image-editor').cropit({
              exportZoom: 0.5,
              imageBackground: true,
              imageBackgroundBorderWidth: 50
          });
    
        $('.image-editor').cropit('imageSrc', $("#current-avatar").attr('src'));
    
        $('form').submit(function () {
            // Move cropped image data to hidden input
            var imageData = $('.image-editor').cropit('export');
            $('.hidden-image-data').val(imageData);
        });
    
    }).apply(this, [jQuery]);
    

    since I have not found an answer to the solution anywhere, I decided to leave here, for everyone who needs it. I hope you find it helps.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决