compare image similarity using php - php

I am searching for a way to identify similar png images with same size. The images are not the exact duplicates. For example If one image has a clip art of a bird, and another image has the same clip art but it is rotated, I want to identify both of them are similar. I want to write an algorithm do this using php.I have tried out this using javasript. What i am doing is convert the image into base64 and compare both the values using hamming distance. But as far I know this will not identify advanced techniques such as scaling, rotating. So what I want it to write an algorithm to do those things in php.Any ideas? This is what I have tried out using javascript and html5 canvas.
function newFunction()
{
var imageHeight = image.naturalHeight;
var imageWidth = image.naturalWidth;
var image2Height = image2.naturalHeight;
var image2Width = image2.naturalWidth;
var data3=[];
var imageData = context.getImageData(0,0,imageWidth,imageHeight);
var image2Data = context2.getImageData(0,0,image2Width,image2Height);
var data = imageData.data;
var data2 = image2Data.data;
function _arrayBufferToBase64( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
//str = String.fromCharCode.apply(null, data); // "ÿ8É"
// str2 = String.fromCharCode.apply(null, data2); // "ÿ8É"
// to Base64
b64 = _arrayBufferToBase64(data);
b64_2 = _arrayBufferToBase64(data2 );
console.log("64 base"+b64_2);
//
var toReturn = 0;
var firstBytes =new Uint8Array(1024);
var secondBytes=new Uint8Array(1024);
var different=new Uint8Array(1024);
// firstBytes = Convert.FromBase64String(first64);
// secondBytes = Convert.FromBase64String(second64);
different = 0;
var mylength;
if(b64.length>b64_2.length)
{
mylength=b64.length;
}
else
{
mylength=b64_2.length;
}
for (var index = 0; index < mylength; index++) {
different = (b64[index] ^ b64_2[index]);
while (different != 0) {
toReturn++;
different &= different - 1;
}
}
var percentage=(toReturn/((image2Height*image2Width)*2))*100;
if(percentage >=100)
{
percentage=100;
}
alert("Difference is "+percentage+" to return" +toReturn + " data1 length"+data.length+ " data2 length"+data2.length);
}
This function works well without any errors. But it won't recognized advanced features like scaling and rotating. Give me some ideas how to do this using php.

Related

Fatal error: Uncaught Error: Class 'Func' not found php

My Questions is Find a 7 letter string of characters that contains only letters from
acegikoprs
such that the gen_hash(the_string) is
675217408078
if hash is defined by the following pseudo-code:
Int64 gen_hash (String s) {
Int64 h = 7
String letters = "acegikoprs"
for(Int32 i = 0; i < s.length; i++) {
h = (h * 37 + letters.indexOf(s[i]))
}
return h
}
For example, if we were trying to find the 7 letter string where gen_hash(the_string) was 677850704066, the answer would be "kppracg".
Solution
test1.php
I did that question solve in php, I am unable to run this code I am in php i don't have that much knowledge regarding php class and their function, Can any one solve this code and describe me. thanks in advance i will be very great full if anyone help me.
<?php
$set = "acdegilmnoprstuw";
$CONST_HASH = 7.0;
$CONST_MULT = 37.0;
$hash = new Func(function($string = null) use (&$CONST_HASH, &$CONST_MULT, &$set) {
$_hash = $CONST_HASH;
for ($i = 0.0; $i < get($string, "length"); $i++) {
$_hash = _plus(to_number($_hash) * to_number($CONST_MULT), call_method($set, "indexOf", get($string, $i)));
}
return $_hash;
});
$decode = new Func(function($_hash = null) use (&$CONST_MULT, &$Math, &$set) {
$decoded = ""; $positionsInSet = new Arr();
for ($i = 0.0; $_hash > $CONST_MULT; $i++) {
set($positionsInSet, $i, call_method($Math, "floor", (float)(to_number($_hash) % to_number($CONST_MULT))));
$_hash /= 37.0;
}
for ($i = to_number(get($positionsInSet, "length")) - 1.0; $i >= 0.0; $i--) {
$decoded = _plus($decoded, get($set, get($positionsInSet, $i)));
}
return $decoded;
});
I realize that this question was asked well over a year ago and I'm only just stumbling on it right now but seeing as there hasn't been an answer I figured I'd answer it.
You used a third party JavaScript to PHP converter utility and expected the demo to work out of the box. You should have read up on it's usage as it clearly states in the ReadMe.md that, ...this tool is using esprima JavaScript parser with rocambole to walk the AST and escope to figure out the variable scope, hoist function declarations and so on...
The developer goes on to say, After AST manipulation tools/codegen.js generates the PHP code by walking the tree. Now here's where it gets good. Pay attention now..
Various constructs get wrapped in helper functions, for instance,
property access, method calls and + operator. The runtime helpers
can be found in php/helper and there are a bunch of classes in
php/classes for Array, RegExp and such. All this PHP gets packaged
into your output file, or you can save it to a standalone runtime and
reference that from your output file like so:
js2php --runtime-only > runtime.php
js2php --runtime runtime.php example.js > example.php
You can also specify the output file using -o or --out and you can
compile multiple input files into one output file like so:
js2php -o example.php file1.js file2.js
So as you can see my friend, to get your code to work you merely need to include the runtime helpers functions so your converted script can be interpreted. I'm not sure as to which files it'll take to get your script to parse correctly, however now that I've pointed you in the right direction I'm confident you'll be able work it out yourself.
Happy coding..
=)
Instead of assigning the inline function with new operator to variable, create a separate functions encode and decode where you can do the hashing and matching the hash code.
Let me give you the snippet of how to do it. I am assuming that your using plain PHP.
/* Call to function encode which returns you the encoded value and store in $encode variable */
$encode = encode($par1, $par2);
/* Call to function decode which returns you the decoded value and store in $decode variable */
$decode = decode($par1, $par2);
/* Function to encode your code */
function encode($par1, $par2){
return $encode_value
}
/* Function to decode your code */
function decode($par1, $par2){
return $decode_value
}
I have written this in Javascript to generate both Hash String and Number
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var gen = gen_hash('kppracg');
document.write("kppracg hash value is ", gen);
document.write('<br><br>');
var gen = gen_hash('iorocks');
document.write("iorocks hash value is ", gen);
var hash = 675217408078;
var gen_rev = gen_hash_rev(hash);
document.write('<br><br>');
document.write("675217408078 hash value is ", gen_rev);
function gen_hash(s) {
var h = 7;
var acegikoprs = "acegikoprs";
for(var i = 0; i < s.length; i++) {
h = (h * 37 + acegikoprs.indexOf(s[i]));
}
return h;
}
function gen_hash_rev(hash) {
var arr_values = ['a','c','e','g','i','k','o','p','r','s'];
var min = 0;
var max = 99999999;
while (min <= max) {
var final_result = "";
var tempInt = parseInt(((max - min) / 2) + min);
var arr_tempInt = num_array(tempInt);
for(var i = 0; i < arr_tempInt.length; i++) {
final_result = final_result + arr_values[arr_tempInt[i]];
}
var result = gen_hash(final_result);
if(result < hash) {
min = tempInt + 1;
}
else if( result > hash) {
max = tempInt - 1;
}
else {
return final_result;
}
}
}
function num_array(num){
var output = [],
sNumber = num.toString();
for (var i = 0, len = sNumber.length; i < len; i += 1) {
output.push(+sNumber.charAt(i));
}
return output;
}
</script>
</body>
</html>

google chart - Assigning random colors to data

My code is:
['checkio','money'],
<?php while($row = mysql_fetch_array($que)){ ?>
['<?php echo $row['checkio']?>' , <?php echo $row['money']?>],
<?php } ?>
According to my sources I should use a loop.
The problem with using a loop is that it cannot specify a separate color..
Its result is:
['checkio','money']
['in',1000]
['out',200]
all the data are the same color.
So, What should I do?
Not sure which chart are you using, but if you are drawing the chart with javascript, you can set a series color in the options of the chart. Here is an example:
var options = {};
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
options.series={};
for(var i = 0;i < data.getNumberOfRows();i++){
options.series[i]={color:getRandomColor()}
}
Full example: http://jsfiddle.net/z2ewqoe1/

Using stage.toDataUrl ,Shape drawFunc content will not captured

I recently found using stage.toDataURL for saving stage content as a image.(KineticJS version 5.0.1)
Custom Shape drawFunc content with core HTML5 canvas object will not applied in image after saving an image.
###################### Images
Please see attached image to get better clarity.
1)Original canvas(stage).
https://f.cloud.github.com/assets/1320926/2300781/c8167c30-a107-11e3-9b61-acf94005c252.png
2)Image after saving stage content
test1
https://f.cloud.github.com/assets/1320926/2300784/fc5343b6-a107-11e3-8c69-07cccc4d7ac4.png
We see that the vertical string "Sample Text" will not saved or it's invisible whatever it is.
###################### Code
1)Here is my code of shape object where line was printed vertically "Sample Text"
var sampleText = new Kinetic.Shape({
drawFunc: function(context) {
var ctx=this.getContext()._context;
ctx.beginPath();
var maxWidth = 2;
var lineHeight = 25;
var x = 415;
var y = 700;
var text = 'Sample Text';
ctx.font = '15pt Calibri';
ctx.fillStyle = 'green';
//Function for vetical text display
wrapText(ctx, text, x, y, maxWidth, lineHeight);
ctx.closePath();
ctx.fill();
ctx.restore();
},
});
//wrapText function if needed
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var words = text.split('');
var line = '';
//alert(context);
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = context.measureText(testLine);
var testWidth = 20;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
}
2)Stage code for saving an image
stage.toDataURL({
callback: function(dataUrl) {
/*
* here you can do anything you like with the data url.
* In this tutorial we'll just open the url with the browser
* so that you can see the result as an image
*/
$('#theimage').attr('src',dataUrl);
$.ajax({
type: "POST",
url: "save.php",
data: { imageData: dataUrl },
});
}
});
Please advise.
Thanks in advance for your time and consideration.
-Naitik.
You chould not use this.getContext()._context because _context is "private" property (starts with undescore). It is not KinetiJS way. Use context as in an example: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/
Your solution:
var sampleText = new Kinetic.Shape({
drawFunc: function(ctx) {
ctx.beginPath();
var maxWidth = 2;
var lineHeight = 25;
var x = 0;
var y = 0;
var text = 'Sample Text';
ctx.setAttr("font", '15pt Calibri');
ctx.setAttr('fillStyle','green');
//Function for vetical text display
wrapText(ctx, text, x, y, maxWidth, lineHeight);
ctx.closePath();
// KineticJS specific context method
ctx.fillStrokeShape(this);
}
});
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var words = text.split('');
var line = '';
//alert(context);
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = context._context.measureText(testLine);
var testWidth = 20;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
}
Demo: http://jsbin.com/xolen/1/edit
Note: KineticJS's context has not measureText method, so you have to use _context property. I think measureText method will be added soon.

convert php to javascript #1

I'm trying to convert this awesome pathfinding php function from http://granularreverb.com/a_star.php to javascript.
PHP function
function path_float(&$heap, &$values, $i, $index) {
for (; $i; $i = $j) {
$j = ($i + $i%2)/2 - 1;
if ($values[$heap[$j]] < $values[$index])
break;
$heap[$i] = $heap[$j];
}
$heap[$i] = $index;
}
JAVASCRIPT function
var $path_f;
var $path_h;
var $path_g;
var $path_open_heap;
function path_float($path_open_heap, $path_f, i, index) { // return heap & values
var j;
for (; i; i = j) {
j = (parseInt(i) + parseInt(i)%2)/2 - 1;
if($path_f[$path_open_heap[j]] < $path_f[index] ){
break;
}
$path_open_heap[i] = $path_open_heap[j];
}
$path_open_heap[i] = index;
}
I'm not sure if javascript understands for() without all elements? If i try to execute javascript function my browser freezes.
P.s. i'm not interested in pre-written js pathdindings, because i need identical php and js function.
Thanks in advance
You can use for without all the elements in javascript similar to PHP. So that is not the problem.
I think the problem is the float that is returned to J. it could be that it never realy is 0 but might be some large float like 0.00000000001 or something and thus never evaluates to false. Unfortunately I cannot test it as You did not provide any input values.
Try the following:
var $path_f;
var $path_h;
var $path_g;
var $path_open_heap;
function path_float($path_open_heap, $path_f, i, index) { // return heap & values
var j;
for (; i; i = parseInt(j)) {
j = (parseInt(i) + parseInt(i)%2)/2 - 1;
if($path_f[$path_open_heap[j]] < $path_f[index] ){
break;
}
$path_open_heap[i] = $path_open_heap[j];
}
$path_open_heap[i] = index;
}

How we can get that at a particular place marker is present or not

I am making dynamic markers. I got success in that. But here is problem that if there is two same lat-log then it place only one marker there.
Instead of that I want to change the marker icon if there is two same lat-log.
I am taking lat-log from database.
Any help.
Yes, I have found the solution of this problem.
I am using two array
The code is as following:
var contentStrings = new Array();
var markers = new Array();
and getting the position
var pos = marker.getPosition();
var isPresent = false;
var index;
for(var i = 0; i < markers.length; i++) {
if(String(pos) == String(markers[i])) {
isPresent = true;
index = i;
}
}
if(isPresent) {
contentString = contentStrings[index] + '<div><br/> Tutor Name : '+data.name+'<br/>Link : '+data.url+'</div>';
} else {
markers.push(pos);
contentString = '<div> Tutor Name : '+data.name+'<br/>Link : '+data.url+'</div>';
contentStrings.push(contentString);
}
Its really working fine.

Categories