Hi - I want to extract an image from a media field in a table, manipulate it using the Images plug-in (specifically scale and optionally rotate it) and then get the resulting new JSImage object to display in an html area for a report using <img src =…
Is there some html syntax for doing this, or another trick? I suppose I could write the JSImage back to a field in the table and then load using media:///servoy_blobloader in the html area, but I don’t want to create an extra table field for this as these manipulations are only done for various reports…
Hmm, there’s something I’m not getting right in trying to access the image in html. So I tried this:
var image = plugins.images.getImage(record.photo);
image = image.rotate(30);
var imgheight = image.getHeight();
var imgwidth = image.getWidth();
myPict = image.getData();// global media dataprovider
text += ‘’;
and I get a broken image icon. I tried also using globals. and a couple of other things, and nothing’s working.
However, if I write the rotated image to a “real” db field. And then go back and access that field in the <img src = media:///servoy_blobloader… tag, it works.
I thought I’d bump this after two weeks. Does anyone know how to get an image (manipulated through the Images plug-in) to display in an html area WITHOUT having to write the image back into the database first? I can’t seem to get the globals that Bob suggested trying to work, but perhaps I don’t understand his solution.
That’s a really good question. I was hoping for something like “globals:///<your_global_media_field>”. I have a clunky workaround, which involves writing a temp file to the local hard drive and then reading it back.
// saving the file in the OS-specific temp directory (need free Tools plugin from it2be.com)
// of course, you can save it anywhere
var tempPath = plugins.it2be_tools.client().tempDir;
var filePath = tempPath + "/my_image.jpg";
var myImage = plugins.images.getImage(record.photo);
myImage = myImage.rotate(30);
myImage = myImage.getData();
var pluginResult = plugins.file.writeFile(filePath, myImage);
if (pluginResult)
{
var myHTML = '<html><img src="file://' + filePath + '"></html>';
}
The challenge you’re going to have with this is that the HMTL rendering engine really doesn’t have a way of reading in in-memory images… that I know of. There are ways of using the DOM to set element attributes via javascript on the client (element.src=xxx), but again this sets a reference to a file or dynamic script that is loaded into the page.
So… brainstorming on ways to get an in-memory image to load into an HTML img element.
One option is to create a servlet plugin like the blobloader, but the problem there is that the servlet can only “see” data on the server. If you have a reference to a byte array on the client the only way the server (and the servlet) can see that is if you persist that image data to the server which is what we’re trying to avoid, right?
Another oh so trivial option is to modify the HTML rendering engine to pull in a byte array from memory.
But I think that the best, and cleanest short term way of solving this is to use chartpacs solution of writing the image to a local file. You could even wrap that up into a plugin for easier re-use.
I guess you could always play with the html area’s DOM to see if setting a src attribute on the Image object works with a byte array.
Thanks for the insights and suggestions. Sean’s solution to write to local files is certainly a better approach (for our solution anyway) than writing to the database, but I agree that it’s clunky. I guess we’ll go this route unless something better is identified…
Regarding exploring the rendering engine DOM to see if setting a src attribute would work - I must admit that I am too DOM challenged to even fully understand what you are suggesting, let alone how to do this - do you have instructions to test to see if this would work?
In Servoy 3.1 B2 it will be possible to combine global variables with the servoy_blobloader, so you will be able to do the following:
var image = plugins.images.getImage(record.photo);
image = image.rotate(30);
var imgheight = image.getHeight();
var imgwidth = image.getWidth();
globals.picture = image.getData();
var html = '.......<img src= "media:///servoy_blobloader?global=picture>....................';
note: If you would declare the global on the fly (dynamically, so not predefined in developer under dataproviders), make sure to set them to a null value (globals.xxx = null;) when you do not need them anymore. this way, they will be cleaned up automatically. Otherwise, them will stay in memory for the entire length of the session.