Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize the image in vue

I upload image from nodejs to vue And put the image in v-card

But the image is cut off

how to resize the image by not cutting?

like image 357
sh_J Avatar asked Dec 10 '18 15:12

sh_J


2 Answers

Use 'contain' attribute in v-img

<v-img src="/picture.png" alt=""
    contain    <!-- causes picture not to be cropped -->
    height="100px"
    width="150px">
</v-img>

check https://vuetifyjs.com/en/components/images#api for more information

like image 77
johnonthetrail Avatar answered Nov 08 '22 22:11

johnonthetrail


I understand this question has been answered long back but adding my answer to help the community.

The code below is not specific just for vuetify.js but this can also be used in any vue.js projects - just change the markups. And if you modify a bit then this can also be used in React, Angular or any JS frameworks.

// If you like - you can move this section into separate file 
// ------- Move from here -------
const dataURItoBlob = (dataURI) => {
  const bytes = dataURI.split(',')[0].indexOf('base64') >= 0
    ? atob(dataURI.split(',')[1])
    : unescape(dataURI.split(',')[1]);
  const mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
  const max = bytes.length;
  const ia = new Uint8Array(max);
  for (let i = 0; i < max; i += 1) ia[i] = bytes.charCodeAt(i);
  return new Blob([ia], { type: mime });
};

const resizeImage = ({ file, maxSize }) => {
  const reader = new FileReader();
  const image = new Image();
  const canvas = document.createElement('canvas');

  const resize = () => {
    let { width, height } = image;

    if (width > height) {
      if (width > maxSize) {
        height *= maxSize / width;
        width = maxSize;
      }
    } else if (height > maxSize) {
      width *= maxSize / height;
      height = maxSize;
    }

    canvas.width = width;
    canvas.height = height;
    canvas.getContext('2d').drawImage(image, 0, 0, width, height);

    const dataUrl = canvas.toDataURL('image/jpeg');

    return dataURItoBlob(dataUrl);
  };

  return new Promise((ok, no) => {
    if (!file.type.match(/image.*/)) {
      no(new Error('Not an image'));
      return;
    }

    reader.onload = (readerEvent) => {
      image.onload = () => ok(resize());
      image.src = readerEvent.target.result;
    };

    reader.readAsDataURL(file);
  });
};

// export default resizeImage; // uncomment once moved to resizeImage.js
// ------- till here - into ./src/plugins/image-resize.js -------

// And then import in whichever component you like in this way:
// import resizeImage from '@/plugins/image-resize.js';

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      originalImg: '',
      resizedImg: '',
    };
  },
  methods: {
    readURL(file) {
      // START: preview original
      // you can remove this section if you don't like to preview original image
      if (!file.type.match(/image.*/)) {
        no(new Error('Not an image'));
        return;
      }

      const reader = new FileReader();
      reader.onload = (e) => this.originalImg = e.target.result;
      reader.readAsDataURL(file); // convert to base64 string
      // END: preview original

      // START: preview resized
      resizeImage({ file: file, maxSize: 150 }).then((resizedImage) => {
        this.resizedImg = URL.createObjectURL(resizedImage);
      }).catch((err) => {
        console.error(err);
      });
      // END: preview resized
    },
  },
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-content>
      <v-container>
        <v-file-input
          accept="image/png, image/jpeg, image/bmp"
          placeholder="Pick an Image"
          prepend-icon="mdi-camera"
          label="Avatar"
          @change="readURL"
        ></v-file-input>
      </v-container>

      <v-container v-if="originalImg">
        <v-row justify="space-around">
          <v-col cols="5">
            <div class="subheading">Original Image</div>
            <img :src="originalImg"/>
          </v-col>
          <v-col cols="5">
            <div class="subheading">Resized Image</div>
            <img :src="resizedImg"/>
          </v-col>
        </v-row>
      </v-container>
    </v-content>
  </v-app>
</div>

Answers that helped me to complete this answer:

  1. Preview an image before it is uploaded
  2. Use HTML5 to resize an image before upload
like image 12
Syed Avatar answered Nov 08 '22 22:11

Syed