CamanJS: Replacing image - camanjs

I'm using CamanJS to add some image processing features to my website, it's a simple and great library but still its documentation is somehow poor.
I'm uploading an image to my website, then I'm applying all the effects on the image uploaded (it's not saved on the Server, I'm modifying it on the client side).
as shown on the official website (http://camanjs.com/guides/#BasicUsage):
function invertColors() {
Caman("#original-img", function () {
this.invert().render();
});
}
The problem is when I re-upload a new image. apparently CamanJS keeps the first image cashed, and the new image is not shown.
when I read about this issue the only place I found an answer for this is here:
CamanJS - change underlying canvas after applying filters/manipulations
but I'm sorry the answer was not that clear for me. so I have to ask it again.
the answer suggested to use reloadCanvasData() but I didn't know exactly how to use it, I tried so many ways but all went in vain!
I tried:
Caman("#original-img", function () {
this.reloadCanvasData();
});
and:
Caman.reloadCanvasData();
etc.
Can anyone provide a working example?
Thanks

I thought I'd help those who came here looking at how to replace PIXEL data rather than just a loaded image:
can1 = document.getElementById("MyCanvas1");
ctx1 = can1.getContext("2d");
var c = <do what ever you need and make a new canvas here>
ctx1.putImageData(c, 0,0); // <---this replaces the pixeldata
Caman("#MyCanvas1", function () {
this.render();
});
This way you can process the image at the pixel level, and then get it back into camanjs.

As a solution what I have done is clear the canvas and have again Inserted an HTML Image tag. before calling Second Image.with camanjs
something like following
function clearCanvas() {
$('#ImageParentDiv').empty();
var htmlTag = '<img src="../images/Loading.gif" id="original-img">';
$('#ImageParentDiv').html(htmlTag);
}

Just call the revert() when you need an original image:
Caman("#original-img", function () {
this.revert();
this.render();
});

Related

Protractor - Unable to access element due to fixed Top navigation bar

I'm facing the following issue in protractor with jasmine
Click/mouse hover not working because of fixed top navigation bar in my application. I need to click/perform mouse hover on a web page.
Unfortunately that element is displaying behind that fixed navigation bar. So scroll till element present & click by x & y coordinates are not working.
My dependencies are :
protractor version 5.2.2
node 8.9.3
selenium standalone 3.13
chrome driver-2.40
chromebrowser v67
OS- Windows 10
Thanks in advance
Try using prototype executeScript
Just try clicking that element from the browser console using id,name or xpath.
For example :
var el = element(by.module('header'));
var tag = browser.executeScript('return arguments[0].click()', el).then(function() {
expect(something).toMatch(something);
});
Another way, along the same lines as what Bharath Kumar S and knowing JeffC's caveat that this approach is cheating, I had a similar issue where the App-Header kept getting in my way of clicking, and I knew I was willing to never need it (so, for instance, to find other ways to navigate or log out and not check for stuff that was on it). I, therefore, did the following, which solved the problem. Note if you refresh the screen, you have to call it again. Also note I am using a number of functions from https://github.com/hetznercloud/protractor-test-helper, which do what you would expect from their names.
var removeAppHeaderIfAny = async function() {
//this function hides the app header
//it is useful to avoid having covers there when Protractor worries that something else will get the click
let found = false;
try {
found = await waitToBeDisplayed(by.className("app-header"), 2000);
} catch (e) {
let s: string = "" + e;
if (s.search("TimeoutError") != 0) flowLog("presumably fine, cover already removed: " + e);
found = false;
}
if (!found) return;
if (found) {
let coverElement = await element(by.className("app-header"));
browser.executeScript(
"arguments[0].style.visibility='hidden';",
coverElement
);
await waitToBeNotDisplayed(by.className("app-header"), 10000);
}
return;
//note after this is called you will not see the item, so you cannot click it
};
As I look at the code, it strikes me one can probably remove the if (found) and associated brackets at the end. But I pasted in something I know has been working, so I am not messing with that.
As indicated up front, I knew I was willing to forego use of the app-header, and it is a bit crude.

How to achieve face detection using web camera

How should I create face detection web application which capture photo and save when face comes in-front of camera.
Which technology currently available to achieve this.
Please Help...
I've been using a wonderful solution called tracking.js (You can find it here). It's simple and wonderful.
Here's an example of how I use it in my code:
var trackerTask;
var tracker = new tracking.ObjectTracker('face');
tracker.setInitialScale(4);
tracker.setStepSize(2);
tracker.setEdgesDensity(0.1);
trackerTask = tracking.track('#vid', tracker, { camera: true })
tracker.on('track', function (event) {
// Do stuff when face was detected
});
// To stop tracking:
setTimeout(function () {
trackerTask.stop();
}, 500);
In the above example, replace #vid with your HTML5 <video> element.

Displaying a png image from base64 data

We are printing labels, which are created by a third party. We serve them directly, passing the base64 data into a blank window, so the user can print it himself.
No matter how many ways I try it, I cannot get the image itself to display.
Here's an excerpt of the data returned from the server (in any other display, it is full of � characters):
PNG
IHDR,Â_gbásRGB®ÎégAMA±üa pHYs88?'õÿ¥IDATx^ì½ ÅöÏî÷íþ÷Û½×T$$1`ÎY130b# ÂQ#%T8äs<d1¢sÆ|õÞëÝ÷_ÏÛSÓÍP}fúLO'ßßÝg'õtWÕTc=ç­·ª 3*Ub%$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmâü«$ÓÍí$×MôqÝn!þîmü 4¥B!ÿ* ü¼¹£Fë&#ú¸n7 L÷¶I~P©R1«PÈ¿Jà?oî¨äº >n£ÛÂM ÄÓ½mWb
ùWI<àçÍ5\7AÒÇmt[¸Iøcº·MòBIYêIÀÈ¿JàÜÜq!Éu }ÜF·A?¦{Û$/U*¢JÅ¥¤þ¯ 9+È¿JàÜÜq!Éu }ÜF·A?¦{Û$O¨ÿ+¢bþn1D]
xÁº¹cBë&#ú¸n7 L÷¶I!bÎ[)FÔ¥¨s)Ô1ùWI<ßÍm\7AÒÇmt[¸Iøcº·Mª(ð&0(±BX%*bÙSÆüDþUä{sG$×MôqÝn!þîm¼ M
¢)ªTR¥¤¨OÃt1Ⱥøûïü«$¨ÈÍ\7AÒÇmt[¸Iøcº·Mò6)0$¼q)ö^1Íó7Ä"ÿ* *rsÇ$×MôqÝn!þîm¼` ×SuI=
¹¹ãBë&#ú¸n7 L÷¶IÙ#ü$W
ùWI<ëÍG\7AÒÇmt[¸Iøcº·MÊOËQBþUäzsÇ$×MôqÝn!þîm²i`¹ªPÈ¿Jà\oî8äº >n£ÛÂM ÄÓ½mRÁqº¹½äº >n£ÛÂM ÄÓ½mR6L¹*n*ò¯ x ×;$¹n¤Ûè¶p ñÇto
S®
ü«$Èõæ#I® éã
etc. etc.
This is what I'm trying to do with it - with various false starts:
vm.getLabelBinaryData = function (labelId){
labelsService.getShippingLabel(labelId).then (
function success(response) {
vm.openWindowForLabels(response.data);
},
function fail(response) {
toastr.error(response.data);
}
);
};
vm.openWindowForLabels = function (responseData) {
//var b64Response = btoa(rawResponse)
var image = new Image();
image.src = 'data:image/png;base64,' + responseData;
var popupWin = window.open('', '_blank', 'width=1000,height=1000');
popupWin.document.open();
popupWin.document.write('<html><head></head><body></body></html>');
popupWin.document.body.appendChild(image);
//popupWin.document.close();
};
When I inspect the HTML, I see this:
<html><head></head><body><img src="data:image/png;base64,�PNG
Strangely, in my browser window, I see the closing img bracket, and closing body and html tags. The fact that it didn;t copy leads em to believe the data is either to long 'too long to edit', or some special character is killing it before it displays.
Either way, I get a broken image icon.
I'm stumped.
UPDATE:
I found a sample here:
https://en.wikipedia.org/wiki/Data_URI_scheme
so I plugged than in to my code:
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
...and it indeed shows the red dot just fine.
This strongly suggests that my code is working fine and that the problems lies with parsing the data properly. (I have verified with the API dev that he is seeing a working image in POSTMAN.)

leaflet no internet detection and notification

If for example, my wifi goes offline, in leaflet i see new map areas grey but no notification about what really happening.
if i open the console i see:
GET https://a.tiles.mapbox.com/v4/image.png?access_token=correct_token
net::ERR_INTERNET_DISCONNECTED
anyone knows a way to catch such events and displaying a custom warning?
I already tried catching:
$scope.$watch('tileerror', function (error, tile) {
alert("No coonection");
});
p.s. using angular-leaflet-directive
EDIT: as pointed out by Ghybs in the comments there is indeed a tileerror event firing from L.TileLayer, however as far as i can see it's not implemented in Angular Leaflet Directive, please correct me if i'm wrong.
L.TileLayer does have an option for setting a replacement image when the tile cannot be loaded called: errorTileUrl:
URL to the tile image to show in place of the tile that failed to load.
new L.TileLayer(URL, {
errorTileUrl: 'error.png'
});
http://leafletjs.com/reference.html#tilelayer-errortileurl
If you need to preform some logic when tiles fail to load you could overwrite L.TileLayer's _tileOnError method:
L.TileLayer.include({
_tileOnError: function (done, tile, e) {
// Do your stuff
alert('whooops!');
// Leaflet stuff
var errorUrl = this.options.errorTileUrl;
if (errorUrl) {
tile.src = errorUrl;
}
done(e, tile);
}
});
https://github.com/Leaflet/Leaflet/blob/master/src/layer/tile/TileLayer.js#L96

WMS GetFeatureInfo; multiple layers, different sources

I'm developing a web application using GeoExt, OpenLayers and having my own GeoServer to serve various maps. Still, I want to let the user add other WMS's if needed, to be able to play around with all desired layers.
Thus, my problem with the GetFeatureInfo request. Right now I have a toolbar button attached to geoext's map panel,
new GeoExt.Action({
iconCls: "feature",
map: map,
toggleGroup: "tools",
tooltip: "Feature",
control: featureControl
})
its control attribute being
var featureControl = new OpenLayers.Control.WMSGetFeatureInfo({
queryVisible: true,
drillDown: true,
infoFormat:"application/vnd.ogc.gml"
});
I've also defined an event listener to do what I really want once I receive the responses, but that is not relevant here. My problem is the following:
Considering the user clicks on a point where there are 2+ visible layers and at least one of them is from a different source, OpenLayers will have to do one AJAX request per different source and, from OpenLayers own documentation,
Triggered when a GetFeatureInfo response is received. The event
object has a text property with the body of the response (String), a
features property with an array of the parsed features, an xy property
with the position of the mouse click or hover event that triggered the
request, and a request property with the request itself. If drillDown
is set to true and multiple requests were issued to collect feature
info from all layers, text and request will only contain the response
body and request object of the last request.
so, yeah, it will obviously wont work like that right away. Having a look at the debugger I can clearly see that, giving two layers from different sources, it actually DOES the request, it's just that it doesn't wait for the first's response and jumps for the next one (obviously, being asynchronous). I've thought about doing the requests one-by-one, meaning doing the first one as stated above and once it's finished and the response saved, go for the next one. But I'm still getting used to the data structure GeoExt uses.
Is there any API (be it GeoExt or OpenLayers) option/method I'm missing? Any nice workarounds?
Thanks for reading :-)
PS: I'm sorry if I've not been clear enough, english is not my mother tongue. Let me know if something stated above was not clear enough :)
i Hope this help to someone else, I realized that: you're rigth this control make the request in asynchronous mode, but this is ok, no problem with that, the real problem is when the control handle the request and trigger the event "getfeatureinfo" so, i modified 2 methods for this control and it works!, so to do this i declare the control first, and then in the savage mode i modified the methods here is de code:
getInfo = new OpenLayers.Control.WMSGetFeatureInfo({ drillDown:true , queryVisible: true , maxFeatures:100 });
//then i declare a variable that help me to handle more than 1 request.....
getInfo.responses = [];
getInfo.handleResponse=function(xy, request) { var doc = request.responseXML;
if(!doc || !doc.documentElement) { doc = request.responseText; }
var features = this.format.read(doc);
if (this.drillDown === false) {
this.triggerGetFeatureInfo(request, xy, features);
} else {
this._requestCount++;
this._features = (this._features || []).concat(features);
if( this._numRequests > 1){
//if the num of RQ, (I mean more than 1 resource ), i put the Request in array, this is for maybe in a future i could be need other properties or methods from RQ, i dont know.
this.responses.push(request);}
else{
this.responses = request;}
if (this._requestCount === this._numRequests) {
//here i change the code....
//this.triggerGetFeatureInfo(request, xy, this._features.concat());
this.triggerGetFeatureInfo(this.responses, xy, this._features.concat());
delete this._features;
delete this._requestCount;
delete this._numRequests;
// I Adding this when the all info is done 4 reboot
this.responses=[];
}
}
}
getInfo.triggerGetFeatureInfo= function( request , xy , features) {
//finally i added this code for get all request.responseText's
if( isArray( request ) ){
text_rq = '';
for(i in request ){
text_rq += request[i].responseText;
}
}
else{
text_rq = request.responseText;
}
this.events.triggerEvent("getfeatureinfo", {
//text: request.responseText,
text : text_rq,
features: features,
request: request,
xy: xy
});
// Reset the cursor.
OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");}
Thanks, you bring me a way for discover my problem and here is the way i solved, i hope this can help to somebody else.
saheka's answer was almost perfect! Congratulations and thank you, I had the same problem, and with it I finally managed to solve it.
What I would change in your code:
isArray() does not work, change it like this: if(request instanceof Array) {...} at the first line of getInfo.triggerGetFeatureInfo()
to show the results in a popup this is the way:
My code:
getInfo.addPopup = function(map, text, xy) {
if(map.popups.length > 0) {
map.removePopup(map.popups[0]);
}
var popup = new OpenLayers.Popup.FramedCloud(
"anything",
map.getLonLatFromPixel(xy),
null,
text,
null,
true
);
map.addPopup(popup);
}
and in the getInfo.triggerGetFeatureInfo() function, after the last line, append:
this.addPopup(map, text_rq, xy);
A GetFeatureInfo request is send as a JavaScript Ajax call to the external server. So, the requests are likely blocked for security reasons. You'll have to send the requests to the external servers by a proxy on your own domain.
Then, configure this proxy in openlayers by setting OpenLayers.ProxyHost to the proper path. For example:
OpenLayers.ProxyHost = "/proxy_script";
See http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#ProxyHost for more background information.

Resources