I am new to the Google App Engine and I am trying to use the Blobstore to store images that I want to display later on.
The image storage works fine. Now I want to dynamically change some images in my html code. Therefore I need a method of getting the images out of the blobstore and passing them. I am using Python. I found the get_serving_url-command, which seemed to be the perfect fit. Sadly, this causes an Error and I seem to be unable to fix it.
My basic code looks like this:
blob_key = "yu343mQ7kT4344N434ewQ=="
if blob_key:
blob_info = blobstore.get(blob_key)
if blob_info:
img = images.Image(blob_key=blob_key)
url = images.get_serving_url(blob_key)
...
Everytime the function gets called, I get the following Error in my Log Console.
File "C:\Program Files
(x86)\Google\google_appengine\google\appengine\ext\remote_api\remote_api_stub.py",
line 234, in _MakeRealSyncCall
raise pickle.loads(response_pb.exception())
AttributeError: 'ImagesNotImplementedServiceStub' object has no
attribute 'THREADSAFE'
I have no idea how to fix it or if I am doing something terribly wrong.
I am very grateful for your support! Thank you in advance!
Have a nice day
You probably need an instance of BlobKey so if you are getting blob_info successfully try:
img = images.Image(blob_key=blob_info.key())
url = images.get_serving_url(blob_info.key())
Related
I am using prawnpdf/pdf-inspector to test that content of a PDF generated in my Rails app is correct.
I would want to check that the PDF file contains a link with certain URL. I looked at yob/pdf-reader but haven't found any useful information related to this topic
Is it possible to test URLs within PDF with Ruby/RSpec?
I would want the following:
expect(urls_in_pdf(pdf)).to include 'https://example.com/users/1'
The https://github.com/yob/pdf-reader contains a method for each page called text.
Do something like
pdf = PDF::Reader.new("tmp/pdf.pdf")
assert pdf.pages[0].text.include? 'https://example.com/users/1'
assuming what you are looking for is at the first page
Since pdf-inspector seems only to return text, you could try to use the pdf-reader directly (pdf-inspector uses it anyways).
reader = PDF::Reader.new("somefile.pdf")
reader.pages.each do |page|
puts page.raw_content # This should also give you the link
end
Anyway I only did a quick look at the github page. I am not sure what raw_content exactly returns. But there is also a low-level method to directly access the objects of the pdf:
reader = PDF::Reader.new("somefile.pdf")
puts reader.objects.inspect
With that it surely is possible to get the url.
I have a models.ImageField which I sometimes populate with the corresponding forms.ImageField. Sometimes, instead of using a form, I want to update the image field with an ajax POST. I am passing both the image filename, and the image content (base64 encoded), so that in my api view I have everything I need. But I do not really know how to do this manually, since I have always relied in form processing, which automatically populates the models.ImageField.
How can I manually populate the models.ImageField having the filename and the file contents?
EDIT
I have reached the following status:
instance.image.save(file_name, File(StringIO(data)))
instance.save()
And this is updating the file reference, using the right value configured in upload_to in the ImageField.
But it is not saving the image. I would have imagined that the first .save call would:
Generate a file name in the configured storage
Save the file contents to the selected file, including handling of any kind of storage configured for this ImageField (local FS, Amazon S3, or whatever)
Update the reference to the file in the ImageField
And the second .save would actually save the updated instance to the database.
What am I doing wrong? How can I make sure that the new image content is actually written to disk, in the automatically generated file name?
EDIT2
I have a very unsatisfactory workaround, which is working but is very limited. This illustrates the problems that using the ImageField directly would solve:
# TODO: workaround because I do not yet know how to correctly populate the ImageField
# This is very limited because:
# - only uses local filesystem (no AWS S3, ...)
# - does not provide the advance splitting provided by upload_to
local_file = os.path.join(settings.MEDIA_ROOT, file_name)
with open(local_file, 'wb') as f:
f.write(data)
instance.image = file_name
instance.save()
EDIT3
So, after some more playing around I have discovered that my first implementation is doing the right thing, but silently failing if the passed data has the wrong format (I was mistakingly passing the base64 instead of the decoded data). I'll post this as a solution
Just save the file and the instance:
instance.image.save(file_name, File(StringIO(data)))
instance.save()
No idea where the docs for this usecase are.
You can use InMemoryUploadedFile directly to save data:
file = cStringIO.StringIO(base64.b64decode(request.POST['file']))
image = InMemoryUploadedFile(file,
field_name='file',
name=request.POST['name'],
content_type="image/jpeg",
size=sys.getsizeof(file),
charset=None)
instance.image = image
instance.save()
I having been trying to write a script that scrapes a page for images the way it has been outlined in
"Save all image files from a website".
I tested that method with another page and it worked fine, but when inserting my link to scrape data:image URIs, which look like:
data:image/jpg;base64,/9j/4FEJFOIEJNFOEJOIAD//gAQTGFGRGREGg2LjEwMAD/2wBDAAgEBAQEREGREWGRWEGUFBQYGBgYGBgYGB...
I get an error beginning with initialize': File name too long and ending in (Errno::ENAMETOOLONG).
Has anyone found a way to deal with situations like this?
data:image URLs actually contain the image inline as base 64. All you need to do is grab that data and decode it:
require 'base64'
File.open(File.basename(uri),'wb'){ |f| f.write(Base64.decode64(url[/base64,(.*)/, 1])) }
I am running an MVC3 app on Mono/linux and everything is working fine with the exception of an image upload utility. Whenever an image upload is attempted i get the Invalid Parameter error from within the method below:
System.Drawing.GDIPlus.CheckStatus(status As Status) (unknown file): N 00339
System.Drawing.Bitmap.SetResolution(xDpi As Single, yDpi As Single)
I've googled this error extensively and have found that the Invalid parameter error can often be misleading, and could fire if for example there was an error with the upload itself, or if the image was not fully read. This runs fine on IIS/Windows, but I've not been able to get it to work in Mono.
Apache2
Mono 2.10.8.1
Am i missing something simple or do i need to find a different way to handle image manipulation for mono?
After doing quite a bit of testing, I was able to determine the root of my error. I was attempting to use the Image.HorizontalResolution and Image.VerticalResolution properties for Bitmap.Resolution . While these properties were set on the initial upload (where the file is read into a stream from the tmp directory), when i posted back with the base64 encoded string of the image itself, it appears these values were lost somehow. Because of this the SetResolution method failed.
For whatever reason i do not have this issue on IIS/Windows, the properties exist in both circumstances.
I encountered a similar issue. A Bitmap loaded from disk, reported bmp.HorizontalResolution==0 and bmp.VerticalResolution==0 when they were both==300. This behaviour does not occur on Windows.
A bit more digging, I found that the following test fails:
[Test]
public void GDI_SetResoltion()
{
var b1 = new Bitmap (100, 100);
Assert.That (b1.HorizontalResolution, Is.Not.EqualTo (0));
Assert.That (b1.VerticalResolution, Is.Not.EqualTo (0));
}
I believe Windows will default resolution to 96 dpi.
I am trying to do something quite simple using Sinatra and RMagick.
Take a image, through a simple form
file upload
Use RMagick to resize it
Then store it in a database for
persistence (irrelevant)
But after going through the RDocs and endless head banging testing
I can't seem to get the form image to a RMagick object cleanly.
This is the horrible thing that is currently working for me:
def image_resize(img_data)
filecount = rand
writer = File.new("/tmp/#{filecount}.jpg", "w")
writer.puts(img_data)
writer.close
resized_image = Magick::ImageList.new("/tmp/#{filecount}.jpg").first
resized_image.crop_resized!(100,100, Magick::NorthGravity)
resized.format = 'jpeg'
resized_image.to_blob
end
#call the method with my form image data
image_resize(params[:image][:tempfile].read)
So how do I do the obvious right thing and just stick my form image data straight into a RMagick object without having to write and read the disk.
I have tried various ways of reading in Magick::Image and ImageLists but have only got an abundance of errors barfed at me.
Thanks for any kind of direction
-1.2.
You need to get the path from the tempfile and pass that to Magick::Image’s read.
Here’s an example:
post "/upload-photo" do
image = Magick::Image.read(params[:image][:tempfile].path)[0]
image.crop_resized! 100, 100, Magick::CenterGravity
store_image_data image.to_blob
redirect "/done"
end
Or you can read straight from the ActionDispatch::Http::UploadedFile like so:
image = Magick::Image.from_blob(params[:image].read)