Comments (24)
Hello, @simioluwatomi!
I'm not @zefexdeveloper, so I can't share the code snippets, but this task should be pretty trivial. Do you want to download image on the backend or send the cropped image from the frontend to the backend?
I've actually figured this out. Thank you!
from vue-advanced-cropper.
I will investigate this possibility. Maybe I should add the prop roundCoordinates
, but it's the pretty straightforward solution.
from vue-advanced-cropper.
Please update to 0.16.0
version.
from vue-advanced-cropper.
Yes, I thought out and decided that's pretty optimal solution. Nonetheless, there is workaround to disable the rounding coordinates, but I couldn't come out with any situation where it might be needed.
from vue-advanced-cropper.
@Norserium Just updated here and it saved me a few lines of code rounding numbers 😆 Thank you
from vue-advanced-cropper.
Hello, @zefexdeveloper!
I didn't understand your problem clearly. How do you check the size of an image at the backend and frontend?
Could you try to use canvas.toBlob(callback, 'image/jpeg')
method to get the blob, instead of using canvas.toDataURL
and your custom method?
from vue-advanced-cropper.
Hi @Norserium, the file size on the back end depends on what technology you are using, this project I'm using Laravel (PHP) and it's just a matter of calling getSize
but as we are talking about validation here, the validation rule itself will check if the file size is bigger than what was specified.
If you select an image, let's say with 500kb and console.log
the base64
on Chrome it will show you the file size.
This was a 334kb image selected, turned 3.9mb:
I will try this canvas.toBlob
, didn't know it existed.
from vue-advanced-cropper.
It's better to use Blob.size
property to check the size of sending image.
from vue-advanced-cropper.
@Norserium Yes, but it doesn't change the problem of having different file size on selecting and when sending. For example, the front end validation is when you select a file right? This way you can check if the file isn't bigger than 5mb, but when you crop, the file size is way bigger. The validation on the back end is when sending the image, so I can't put like 5mb max on the back end as well cause if the user selects an image on the front end that is let's say 4.5mb and crops, it will turn at least 15mb more or less so the backend won't allow it.
I will try this canvas.toBlob
cause working with base64
is problematic cause of this, the image size is way bigger.
from vue-advanced-cropper.
What's the image type do you use for converting to base64
? Default is image/png
, so if you upload .jpg
image result might be larger.
from vue-advanced-cropper.
@Norserium I was using the code above, it's pretty much the same as canvas.toBlob
as I was reading and canvas.toBlob
doesn't work on Edge and doesn't have the quality argument in most browsers so it will be pretty much the same. (or worse with less support: https://caniuse.com/#search=toblob)
Do you have a project set up where you can call canvas.toBlob
and check if the file size is bigger (or a lot bigger) than it should be?
from vue-advanced-cropper.
The conceptual problem consists in impossibility to preserve size of the image after drawing one at an canvas and getting one from that canvas.
I can advise two ways:
- Use
image/jpeg
during conversion (toBlob
,toDataURL
). You won't get the same size, but it should be pretty similar. - Crop the image on your backend by sending full image and coordinates to it.
Do you have a project set up where you can call canvas.toBlob and check if the file size is bigger (or a lot bigger) than it should be?
I've made it now:
https://codesandbox.io/s/vue-avanced-cropper-comparing-file-sizes-1xl7r
from vue-advanced-cropper.
@Norserium The second alternative sounds good, this way I can validate the size both on the front and on the back end without the cropping difference.
I will be trying to second alternative and see if it works nice. Thank you very much.
from vue-advanced-cropper.
@zefexdeveloper, did you solve your problem?
from vue-advanced-cropper.
@Norserium Sorry the delay answering. I refactored the code in order to send the coordinates and crop on the backend but the libraries asks for integer instead of float when cropping so I had to round them. Is it possible to have an option to return the coordinates as integer?
from vue-advanced-cropper.
@Norserium Thank you very much, it will help me a lot, right now I have to round each one and it's pretty shitty solution. Most of the others croppers I saw they have the coordinates as integers, having both in float for precision and integer for compatibility would be great.
from vue-advanced-cropper.
Anything on this @Norserium ? Thank you
from vue-advanced-cropper.
I'm pretty busy on other projects, so I've postponed the implementing of this feature to this weekends. Sorry for the delay.
from vue-advanced-cropper.
@Norserium That is ok, wish you luck. Thank you very much.
from vue-advanced-cropper.
@Norserium You rock, thank you for this. It's rounded by default now right?
from vue-advanced-cropper.
@Norserium Sorry the delay answering. I refactored the code in order to send the coordinates and crop on the backend but the libraries asks for integer instead of float when cropping so I had to round them. Is it possible to have an option to return the coordinates as integer?
Please how did you do this? Care to share some code snippets? I'm also using Laravel and I'm at my wits end because I don't know how to get the file object. Please help out. Thank you
from vue-advanced-cropper.
Hello, @simioluwatomi!
I'm not @zefexdeveloper, so I can't share the code snippets, but this task should be pretty trivial. Do you want to download image on the backend or send the cropped image from the frontend to the backend?
from vue-advanced-cropper.
@simioluwatomi
Usually when you figure things out, you share it for others..
from vue-advanced-cropper.
Here you go
Vue component
<template>
<div>
<cropper
:src="image"
:stencil-props="{ aspectRatio: 1 }"
ref="cropper"
class="border border-dashed w-100"
style="min-height: 300px; max-height: 600px"
></cropper>
<p class="mt-3 text-center text-danger">{{ errorMessages[0] }}</p>
<div class="btn-options justify-content-around my-3">
<ValidationProvider rules="required|ext:jpg,png,jpeg|size:1024" ref="provider">
<b-button variant="outline-primary" @click="$refs.file.click()">
<input type="file"
ref="file"
v-show="false"
accept="image/png,image/jpeg,image/jpg"
@change="loadImage($event)">
Select image
</b-button>
</ValidationProvider>
<b-button variant="secondary" @click="rotate" :disabled="invalid">Rotate</b-button>
<b-button variant="primary" type="submit" @click="upload" :disabled="invalid">Upload</b-button>
</div>
</div>
</template>
<script>
import {Cropper} from "vue-advanced-cropper";
import iziToast from "izitoast";
import {ValidationProvider, ValidationObserver, extend} from 'vee-validate';
import {required, ext, size} from 'vee-validate/dist/rules';
extend('required', {
...required,
message: 'This field is required.'
});
extend('ext', {
...ext,
message: 'The selected file must be an image.'
});
extend('size', {
...size,
message: "The selected image should not be greater than 1 megabyte."
});
export default {
name: "ImageUploadComponent",
components: {
Cropper,
ValidationProvider,
ValidationObserver
},
props: {
'user': {
type: Object,
required: true
},
},
data() {
return {
image: null,
avatar: null,
invalid: true,
errorMessages: '',
};
},
methods: {
async loadImage(event) {
const {errors, valid} = await this.$refs.provider.validate(event);
if (errors) {
this.errorMessages = errors;
}
if (valid) {
// Reference to the DOM input element
let input = event.target;
// Ensure that you have a file before attempting to read it
if (input.files && input.files[0]) {
// create a new FileReader to read this image and convert to base64 format
let reader = new FileReader();
// Define a callback function to run, when FileReader finishes its job
reader.onload = (event) => {
// Note: arrow function used here, so that "this.imageData" refers to the imageData of Vue component
// Read image as base64 and set to imageData
this.image = event.target.result;
};
this.avatar = input.files[0];
// Start the reader job - read file as a data url (base64 format)
reader.readAsDataURL(this.avatar);
}
this.invalid = false;
}
},
rotate() {
let image = document.createElement("img");
image.crossOrigin = "anonymous";
image.src = this.image;
image.onload = () => {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
if (image.width > image.height) {
canvas.width = image.height;
canvas.height = image.width;
ctx.translate(image.height, image.width / image.height);
} else {
canvas.height = image.width;
canvas.width = image.height;
ctx.translate(image.height, image.width / image.height);
}
ctx.rotate(Math.PI / 2);
ctx.drawImage(image, 0, 0);
this.image = canvas.toDataURL();
};
},
upload(blob) {
const {canvas} = this.$refs.cropper.getResult();
canvas.toBlob(result => {
let formData = new FormData();
formData.append('avatar', result, this.avatar.name);
axios.post(`/${this.user.username}/avatar`, formData)
.then(function (response) {
// handle success response here
}.bind(this))
.catch(function (error) {
// handle error response here
}.bind(this));
}, 'image/jpeg')
},
},
};
</script>
Controller method
public function __invoke(Request $request, User $user)
{
$request->validate(['avatar' => ['required', 'image', 'max:1024']], [
'max' => 'The uploaded image should not be greater than 1 megabyte.',
]);
$path = $request->file('avatar')->storeAs(
"{$user->id}",
sha1($user->id).'.jpeg',
'uploads'
);
$user->update(['avatar' => $path]);
return response()->json($user);
}
from vue-advanced-cropper.
Related Issues (20)
- More detailed events please?? HOT 2
- I am unable to use Cropper in my bootstrap modal. HOT 2
- Cropper doesn't work after deployment. HOT 20
- Usage of the cropper in Composition API through a composable/util HOT 13
- Bug Cropper: no emit resize-end or move-end events in modal HOT 1
- 你好,如果想修改为支持:选中的区域为任意四边形(四个内角都不能大于180度)而不是矩形,需要修改哪里啊? HOT 1
- No matching version found for vue-advanced-cropper@next HOT 1
- Missing stencil and duplicate view HOT 3
- Question: How to fit image to stencil, when it first loads HOT 2
- issue: getting canvas in composition api with <script setup> HOT 1
- I want to be able to edit the image preview list by clicking on it. HOT 1
- using image restriction 'none' and aspect ratio. HOT 5
- In Vue advanced cropper , the moving class (vue-rectangle-stencil--moving) is not removing automatically when I stop moving the mouse, but if I refresh the page once means , it is removing automatically and working as expected. HOT 1
- Saving/Retrieving cropper settings to re-apply at a later time HOT 1
- How to use defaultVisibleArea with values that have a very narrow or very wide size of square stencil HOT 1
- Wrong Width Height recognition HOT 2
- Image Cropping Failure for larger Images HOT 1
- The cropped image was found to be missing pixels HOT 1
- RTL Support Issue: Incorrect Cropper Behavior with postcss-rt
- Test support / documentation
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vue-advanced-cropper.