Closed justinFather closed 8 years ago
Hi @justinFather, from the docs:
If requested subversion isn't found, original will be returned
It's probably caused by wrong path or you're requesting thumbnail before it actually created, or subversion record is inserted into MongoDB. Try to render template only after callback in .insert()
method is triggered.
versions:Object
original:Object
extension:"jpg"
path:"assets/app/uploads/Images/B5C8sKwNxjjkoLr28.jpg"
size:18744
type:"image/jpeg"
__proto__:Object
thumbnail:Object
extension:"jpg"
path:"assets/app/uploads/Images/B5C8sKwNxjjkoLr28.jpg__thumbnail__.jpg"
typs:"image/jpeg"
__proto__:Object
"assets/app/uploads/Images/B5C8sKwNxjjkoLr28.jpg__thumbnail__.jpg"
is wrong path.
If you change it to: "assets/app/uploads/Images/B5C8sKwNxjjkoLr28__thumbnail__.jpg"
, it should work
If Imagemagick.crop()
has a callback, you should update record in MongoDB there, after image is cropped.
Even though I used Imagemagick.crop callback, onAfterUpload would return before the callback. I need something like 'promise'. I will try it.
Use fibers/future
's .wait()
method
I did some experiment just before.
I copied all jpg in assets/app/uploads/Images/
to temp directory and deleted all jpg files and confirmed my app displayed broken image sign. and then I stopped my app and restore all jpg files to the directory and restart my app.
It shows thumnails 200x200( it still has the name B5C8sKwNxjjkoLr28.jpg__thumbnail__.jpg
)
I see. I will try .wait()
I copied all jpg in assets/app/uploads/Images/ to temp directory and deleted all jpg files and confirmed my app displayed broken image sign. and then I stopped my app and restore all jpg files to the directory and restart my app.
So, it was the cache. I recommend to always disable cache in browser when working with this kind of libraries
I think even though i use the cache, if i use .wait()
properly, it will work fine.
I will try it 1-2 hours later because now i'm not available to code now.
It's always better to use async code, then co-routines. If you need to show thumbnail as soon as it's available - set observer on the Client and wait until versions.thumbnail
is added.
Im back. :D
I read your last comment. I confirmed already that versions.thumbnail
was added using console.log( image)
before .link()
call. Is it not enough?
And how about using Meteor.wrapAsync
for Imagemagic.crop
?
I will test it now.
Meteor.wrapAsync
directly uses futures
lib.
I read your last comment. I confirmed already that versions.thumbnail was added using console.log( image) before .link() call. Is it not enough?
- You log this on server?
.link()
called on client?
onAfterUpload: function( fileRef ) {
const cropName = fileRef.path + "__thumbnail__.jpg"
Meteor.wrapAsync( Imagemagick.crop({
srcPath: fileRef.path,
dstPath: cropName,
width: 200,
height: 200,
quality: 0.8,
gravity: "Center"
}))
const upd = {
$set: {
"versions.thumbnail" : {
path: cropName,
type: "image/jpeg",
extension: "jpg"
}
}
}
return Images.update( fileRef._id, upd )
}
There was some improvement that I can see the thumbnail through pressing F5
.
Before that, I had to do as below to see the thumbnail.
I copied all jpg in assets/app/uploads/Images/ to temp directory and deleted all jpg files and confirmed my app displayed broken image sign. and then I stopped my app and restore all jpg files to the directory and restart my app.
post you Client's code here one more time please
I'm using Meteor 1.3 + reactjs
below is reacjs code on client side
this.images().map(( image ) => {
console.log( image ) // <---------------------- here
return (
<li key={image._id}>
<img src={Images.link(image, "thumbnail")} />
</li>
)
})
client side upload part
onChange(e) {
e.preventDefault()
const self = this
_.forEach( e.target.files, function(file) {
const img = new Image()
img.onload = function() {
const { width, height, rate, extension, type } = Meteor.settings.public.uploadConf
const ratio = Math.sqrt( width * height / ( this.width * this.height ) )
processImage( file, this.width * ratio, this.height * ratio, rate, function ( data ){
self.state.currentImage.set( Images.insert({
file: new File( [ Lib.dataURL2Array(data) ], `${file.name}.${extension}`, { type: type } ),
onUploaded: function (error, fileObj) {
if (error) {
console.log('Error during upload: ' + error);
} else {
//alert('File "' + fileObj.name + '" successfully uploaded');
}
},
streams: 'dynamic',
chunkSize: 'dynamic'
}))
})
}
img.src = URL.createObjectURL( file )
})
}
If this code is reactive you can do something like:
this.images().map(( image ) => {
console.log( image ) // <---------------------- here
return (
<li key={image._id}>
<img src={(image.versions.thumbnail) ? Images.link(image, "thumbnail") : '/img/dummy_placeholder.png'} />
</li>
)
})
Yes, mine is reactive!!
I will do it.
It works great!!!
It's what i want!!!
Thank you very much.
BTW there is a little chance what callback of ImageMagick.crop()
called before bytes is actually written to FS, for example after its resized in memory. I'm using gm via this lib and image available as soon as callback is triggered
It works great!!!
:) great!
Hi,
I tried as below
I could see the thumnail file generated on the same directory with original one.
on client side code
'scr' attribute looks like "......id/thumbnail/id.jpg" but the image shown up is not a 200x200 thumbnail. It is just original one.