having problems serving an image stored as a blob from google app engine - I'm trying to view a stored image with the following code
my datastore model is:
class QuestionTemp(db.Model):
picture = db.BlobProperty()
my post call from the initial form is:
class QuestionAsker3(webapp.RequestHandler):
def post(self):
upload_files = self.request.get('file') # 'file' is file upload
tempQuestion = QuestionTemp(picture= db.Blob(upload_files))
tempQuestion.put()
self.response.headers['Content-Type'] = "image/jpeg"
self.response.out.write(tempQuestion.picture)
The image is stored in the blobstore as I can view it in the GAE admin console
"blob viewer".
In chrome the return screen in blank - firefox I get a url and what looks to be a hashcode.
many thanks in advance.
managed to solve the problem - was reading the data into the Blobstore, rather than as a Blob
so the Blob was just storing a references hence had no image data. The .value thing didn't work for me.
Thanks for helping me figure it out #abdul and #adam
Related
In a controller I return a view with data. Along with this data, how can I also send back an image?
The image needs to be loaded via Storage as it's private, I get the image and build an image response in a class.
How can I also return this image response along side my data?
I've tried setting the response to a var in my data and displaying that in img src but it fails to load the image.
Normally I work with url. Storage::url('file.ext') give you a lot of possibility. There is also a way to create temporary url with this method within the Storage facade $url = Storage::temporaryUrl('file.jpg', now()->addMinutes(5)); You have to indicate when the url should expire.
There is another method that I use with drawboard.
You first have to get the content of your image. I don't remember, but I think the get() method of storage do the job. Maybe it's a bit more complex.
Whatever, you have to get the raw data of the image, put it into a variable and send it to the view.
Then, in the src of the image, you do this:
<img src="data:image/png;base64, {{$varToRawData}}" />
Be sure to use the right image/extension
So I am having this issue with ruby, the following code explains what is going on
def image_full(img,options)
if Jjdowns::Application.assets.find_asset("#{img}").nil?
image_full = image_tag("#{img}",options)
else
image_full = image_tag("app/no-image-large.png", options)
end
end
What i am trying to do is run a check if an image exists on my asset server then if it exists show the original image. If there is no image found on the asset server then i want to show a default image.
This code block works for showing the image but the part about showing the default image does not function.
So far my research has turned up nothing in the way of a solution to this issue.
Just to clarify the asset server is a in house "CDN" server and the default image is located on the asset server.
The solution to the problem ended up being the following
def some_image(img,options)
default_img = "dir_to_image/no-image-filler.png"
if ("#{img}") != ''
default_img = "#{img}"
end
some_image = image_tag(default_img, options)
end
The key thing here was that we have an external asset host running on a separate server, and that was the initial problem.
I am looking for good ways to retrieve images from MongoDB and display them. For example, to retrieve a profile picture and display it on a profile page, this is how I am currently doing it:
profile page
block content
h1= session.user.name
img(src='/avatars')
routes
exports.avatars = (req, res) ->
users.find req.session.user, (err, user) ->
if user
res.writeHead('200', {'Content-Type': 'image/png'})
res.end(user.avatar.data, 'binary')
else
res.locals.flash = err
res.render('index', {title: 'Home'})
Basically I render the profile page, and the img tag sends a request back to the server to pick up the picture of the user from the database. Im saving the images as BinData in MongoDB. Not using GridFS because I expect the pictures to be small.
Is there a better way to do this?? I tried to send the image data directly to the jade view using res.render('users/show', {picture: data}) but the img tag didn't like that and I'm not clear on why. Is this approach a dead end?
Any comments/suggestions would be much appreciated. Thanks!
Sending the image data directly to jade view would work if
a) you base64 encoded the image data
b) prefixed with "data:"
But I would not recommend you do this way, you essentially in-lining the image in your html.
You should instead create a separate route to handle your images/avatars.
For example the image source for your avatars should be something like
img(src='http://mydomain.com/avatars/user1.jpg')
When the browser requests this image you then respond with image data retrieved from mongo.
I will try to be as clear as possible to explain my problem. If not, tell me !
Mywebapp is based on Codeigniter. In it, I did a controller in order to show images uploaded by the users. By this way, the images can only be seen by members or authorized people and are not public like in facebook for example (image addresses are just hashed but are public).
I also use the mpdf library to generate a pdf from the content of a web page. To use it, I have in the third party directory the mpdf library. To be able to use it with my formatting, I put in the library directory (in application directory) my mpdf library (just to be able to use it from different controller). I have a pdf controller which is called from the view where I want to generate the pdf.
So the process is : I call a function of the pdf controller from my view. In this function, I call a function of my mpdf library which create a mpdf object (the third party class) and generate the pdf.
The generation of the pdf works great. The only I had is for the images. I explain. In my html document, the image are embedded like that :
<img src="http:localhost/www/myapp/library/image/hashed_name_of_the_image" alt="" />
The image function of the library controller retrieve the image and shows it. But in this function, I can protect or not the access to run it. For example, to force to be a logged user to see an image (if($this->session->userdata(‘logged’) == true)).
If there is no restriction, the generated pdf contains the images. Cool :).
But if I put a restriction, it doesn't. I understand that the mpdf object is the one which is asking to image function to show the image. So the verification failed.
I tried to use a config parameter on the CI instance object before I call the pdf function. For example, set to true a "pdf_conversion" and the conversion finished, set it back to false.
But it doesn't work. When I check the value in the image function, it's still false... It's like the config value is not change for all object but only for th pdf object which has changed it.
Is there a way to do what I want to do ??? With config parameter or anything else !!! I think I misunderstood something but don't know what !
thanks by advance for answers
Bastien
You problem is that then the library "calls" the image function, it is not logged in. So your controller code denies access.
There are two things you can do:
Move the code that generates/gets the image form the controller into a new library. then call that library from the controller and from the PDF library. This is the preferred way.
In the "image" action, find a way to check if the request is coming from the PDF library. Best guess is to look for something in the HTTP headers the PDF library sends. Anyway this is not very secure since HTTP headers can be "faked".
OFF TOPIC: Is there a reason you server the image from a controller action instead of by directly referencing the image file?
CLARIFICATION ON SOLUTION 1
So you'll have a library image.php that looks like this
class Image {
...
function get_image($hash){
[code for getting the image here]
}
...
}
In the controller:
function image($hash) {
$this->load->library('image');
if (if($this->session->userdata(‘logged’) == true)) {
$image = $this->image->get_image($hash);
[send it to the browser]
}
}
In the PDF library
function export($hash) {
$ci =& get_instace();
$ci->load->library('image');
[do pdf stuff]
$image = $ci->image->get_image($hash);
$this->add_image($image);
[do more pdf stuff]
}
This is the idea, the actual details of the implementation are up to you.
This is similar to the problem posted here, but that solution doesn't work for me. Maybe it's because I'm not passing the data in correctly.
I'm pulling screenshots from Flash and displaying them on the page using Jquery:
$SNAPSHOT_PREVIEW.attr("src","data:image/jpg;base64," + imgData);
$HIDDEN_BASE64_STRING.val(imgData);
I had it nice and working where you could save the image to Rails in Flash, but Flash won't allow you invoke a post action without the user pressing a button for security reasons. Makes sense. Anyway, now I can't get Paperclip to save the image coming from the HTML form:
#(photo has_attached_file:image)
#photo = params[:photo]
data = StringIO.new(Base64.decode64(params[:base64_string]))
data.class.class_eval { attr_accessor :original_filename, :content_type }
data.original_filename = "screenshots.jpg"
data.content_type = "image/jpg"
#photo.image = data
Yields the error:
NoMethodError (undefined method `image=' for #<ActiveSupport::HashWithIndifferentAccess:0x8c2e420>):
How do I need to finesse the base64 image data into a paperclip attachment?
For bonus points, do I need the hidden field to pass the data or is there a clever, browser compatible way to use the image src as a form value?
You have the code:
#photo = params[:photo]
params is just a hash, so later, when you call #photo.image, Rails bugs out. Perhaps you want:
#photo = Photo.new(params[:photo])
instead?