I am not sure if this is possible, but I want to store an image in a JavaScript variable or an object and when the page loads, I want to make those images appear where desired.
I want to know if some images are converted to binary form. Can they be converted back to images with JavaScript?
It appears that the OP is requesting how to do data islands in JavaScript, specifically for images. None of the answers previously given provide such a method, so here you go.
Basically, you encode the image as a base64 string and then set that as the source of a DOM element. Setting the source of an Image object to a url is not equivalent, since it requires an addition HTTP connection.
var data = 'data:image/gif;base64,'+
'R0lGODlhAAEwAMQAAJ2M5Me98GRK1DoYyYBr3PHv++Pe99XO81Y50auc6PBkZEgpzbmt7HJa2I57'+
// snip //
'fS3CqU7XGYgE+GqHvrLJ8Tr6qXmqiwAF9CffgnMNqmWHAWNBwwGsKpKsrmJqltOOV69nuYxSkqpo'+
'Tata18rWtrr1rTIIAQA7';
var icon_elem = document.getElementById("icon_here");
icon_elem.src = data;
The above code and a full example can be found here: http://www.kawa.net/works/js/data-scheme/base64-e.html
You can simply use
var img = new Image();
img.src = "http://yourimage.jpg";
to create a DOM image.
A DOM image is an object in memory that contains the image binary form, so there's no need to convert it back to an image since it's already one.
See, this is a simple matter. But the method to approach this problem is not the way you are trying right now.
What you think will work:
We'll store the image (its binary data) in a js variable, and then slap it on the page any time.
How it will work much more easily:
you just have to create a DOM image on the page, and set its source. The browser will fetch the image from the server automatically.
Examples:
ex-1:
var img_src = "http://someserver/yourimage.png";
var node = document.getElementById('the-node-in-which-i-want-my-image');
node.innerHTML = "<img src='"+img_src+"' alt='my image'>";
ex-2: (using jquery) - this is essentially the same as above, only much easier to write:
var img_src = "http://someserver/yourimage.png";
$('#the-node-in-which-i-want-my-image')
.html("<img src='"+img_src+"' alt='my image'>");
Now, there's one more thing: the browser starts fetching the image after this code runs, so the image actually appears a little after you insert it into the DOM.
To prevent this, you can pre-fetch the images using:
var prefetch = new Image();
prefetch.src = "http://someserver/yourimage.png";
Cheers!
Related
I have a problem for getting properties of loaded image in Phaser.js.
Now I resolve it by accessing private variable (a suck method I known...):
var image = game.textures.get("imageA")
console.log("width",image.frames.__BASE.width);
Does anyone has a better solution to get these properties?
Thanks a lot.
Depending on your UseCase, you could use the getSourceImage or get method, of the Texture object.
It is abit longer, also but works (if you need/want the html element ):
var image = game.textures.get("imageA");
console.info(image.getSourceImage().width);
here the link to the documentation
Or you could use the get function of the texture (if you need/want the phaser frame):
var image = game.textures.get("imageA");
console.info(image.get().width);
here the link to the documentation
The parameter for get and getSourceImage are optional, but you could enter a name/index of a frame, if you need a specific frame.
I need to replace some images in an InDesign document with a given file. This happens using the InDesign server, but scripting is almost the same as with regular InDesign, except no user interaction is possible.
What I have is a InDesign Document, the ID of an Rectangle containing some image and the Path to a new image that should replace the image.
The image should be replaced, but the settings like FitOptions etc. should stay the same. Also, the new file shall be embedded in the InDesign Document. There is already some code that sort of works:
function changeImages(doc) {
var arrayLength = changeImage.length;
for (var i = 0; i < arrayLength; i++) {
var fr = doc.textFrames.itemByID(1 * changeImage[i].id);
if (!fr)
continue;
var file = File(imagePath + changeImage[i].file);
fr.place(file);
fr.fit (FitOptions.CONTENT_TO_FRAME);
fr.fit (FitOptions.PROPORTIONALLY);
fr.fit (FitOptions.CENTER_CONTENT);
}
}
This doesn't seem right. Why is it using doc.textFrames when the object is a rectangle? I am actually confused this even works.
Also it just sets some FitOptions, but I want to keep the existing.
I am very new to InDesign scripting, so I am lost here. I am reading the docs and other resources, but I am confused. e.g why is there doc.textFrames.itemByID but nothing like that for other Frames? Do I have to iterate doc.allPageItems and compare ids?
itemByID is a method available for all pageItems and both textFrames and rectangles are subclass of pageItem. So you have access to this method from both, and it'll give the same result. You should be able to use doc.rectangles.itemByID as well. See: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangles.html#d1e201999__d1e202138
But you are right that the description is a bit confusing, it says:
Returns the TextFrame with the specified ID.
which is obviously not the case. If you already have the IDs you want to target, you could use doc.pageItems.itemByID, which is maybe less confusing, since basically you're looking for pageItems when using itemByID.
As for fitting options, they are a property of your rectangle object, so placing a new image shouldn't change the fitting options. If you want to keep the same, simply remove the calls to fit(). See in property list of Rectangle, frameFittingOptions: http://www.indesignjs.de/extendscriptAPI/indesign11/#Rectangle.html
Josef,
I've had the same problem with InDesign CS4 with keeping the original FitOptions. I was never able to figure out how to get the settings currently being used in InDesign CS4.
To get around the problem what I did was to set the value in the Fitting on Empty Frame in the Frame Fitting Options in the InDesign document.
Then in code I used that setting, something like this:
changeImages (app.activeDocument);
function changeImages(doc)
{
with(doc)
{
var rec = doc.rectangles.itemByID(207);
var file = new File("c:\\new_image.png");
rec.place(file);
rec.fit(rec.frameFittingOptions.fittingOnEmptyFrame);
}
}
I'm trying to test something which I might later use in a more complex application however I'm struggling to find why this following code is not working. I'm not that familiar with javascript however I have noticed that there is no such thing as casting?
I have the following piece of code which in Java if casted should work however in this following script, it doesn't. To be more specific the following error gets returned:
Uncaught TypeError: Failed to execute 'putImageData' on 'CanvasRenderingContext2D': No function was found that matched the signature provided. test.html:16
window.onload
Here is the code
<script>
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var imageObject = ctx.getImageData(0,0,100,200);
var stringed = JSON.stringify(imageObject);
var nowShouldBeImage = JSON.parse(stringed);
ctx.putImageData(nowShouldBeImage,0,0);
}
</script>
My question is why is it that the object after being parsed is not getting recognised correctly? What am I missing here? And how would I tackle the lack of this functionality in javascript? ( Maybe not lack of functionality but rather difference from Java)
The JSON object parses files into simple structures.
You're basically getting an array of channel values back, I believe.
.putImageData doesn't work with arrays, but rather with ImageData objects (which may behave like arrays, but are not).
You've got multiple solutions, here, if what you're interested in is sending something to / loading something from the server.
If you want to use XHR, then you can use base64 to go back and forth.
var canvas = getMyCanvas(),
ctx = canvas.getContext("2d"),
encImgData = canvas.toDataURL();
var img = new Image();
img.src = encImgData;
ctx.drawImage(img, 0, 0);
If you want to go through and manually edit that image's pixel-range thereafter, draw it to an offscreen canvas, .getImageData() to match the width and height of the image you cared about, edit the pixels, and .putImageData() using the edited object.
But JSON isn't going to marshal things into specific types for you.
It takes simple data structures, puts them in strings, and outputs those structures into other simple structures.
You can also write a node-modifying function which will be called as each node in the structure is being rebuilt.
If you specifically want to write a function which checks if the node is an array and it's filled with what you assume are per-channel values, and then use ctx.createImageData, and manually loop through and fill each channel of each pixel with the array value, and then return the constructed ImageData object, you can do that, too, I suppose. But that's not going to do you any favours regarding speed.
Java ≠ Javascript, not use javascript as java.
this step seems useless:
var stringed = JSON.stringify(imageObject); //object to string
var nowShouldBeImage = JSON.parse(stringed); //same string to JSON?!?! nothing change... why?!!?
remove the useless step:
var imageObject = ctx.getImageData(0,0,100,200);
//var stringed = JSON.stringify(imageObject); remove this two line
//var nowShouldBeImage = JSON.parse(stringed);
ctx.putImageData(imageObject,0,0);
The object nowShouldBeImage isn't the same of imageObject because inside of this object there are some properties that are particular because are the result of getImageData() that after JSON.stringify are lost (nowShouldBeImage is an instance of Object, imageObject is an instance of ImageData)
You are serializing binary data with JSON. If you really need to do that, try encoding the ImageData object from getImageData() as base64 first.
I have a HTML fragment that I'm objectifying via jQuery for the purpose of extracting some data from it. This fragment has some image resources that I don't want the browser to download. Is there a way to do it.
A simplified version of my current code:
var html = '<p class="data">Blah Blah</p>...<img src="/a/b/...png">...<div>...</div>';
var obj = $(html); // this makes the browser download the contained images as well!!!
var myData = {
item_1: obj.find('.data:first').text(),
item_2: obj.find('.data2:first').text(),
.... // and so on..
};
Unless you think there will be instances of the substring src= in the string that matter to you, you could do:
html = html.replace(/src=/g, "data-src=");
or possibly
html = html.replace(/src\s*=/g, "data-src=");
...to allow for whitespace. That way, the browser won't see the src attribute, and won't trigger the download.
Sometimes the direct approach is best. Of course, if you think there may be src= substrings that will matter in terms of what you're trying to extract, then...
edit
so it looks like i have to somehow convert an image to
https://developer.mozilla.org/en/DOM/CanvasPixelArray
serverside
my current attempts have been to *
Pass a base64 encoded image from the server ... then converting it to binary with atob()
but then i get stuck trying to draw this onto a canvas without having to do something like
var i = new Image();
i.onload = function(){.....}
i.src = "base64 string"
So an even more general statement
I am trying to bypass creating a Image object by any means to display a new image
If your goal is to avoid the use of javascript and to simply embed the image in your page, you can simply do
<img src="data:image/png;base64,UhhIaminbase64...">
If your base64 is obtained dynamically in ajax, then the way to use the decoding library is to create an Image object with the code you made.
An alternate solution would be to send directly the RGB values in a binary array (base64 encoded if you use json) and to iterate client-side on this array in order to change your canvas' imageData. That seems easy enough but somewhat inefficient as you wouldn't have the compression of PNG or JPEG.
With html5 you can do so:
<script>
window.onload = function()
{
var img = new Image();
img.src = "data:image/png;base64,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";
document.body.appendChild(img);
};
</script>
Here is a working example: http://jsfiddle.net/4ZaUu/3/