Jump to content

  • Log In with Google      Sign In   
  • Create Account


Loading PNG In PHP And Returning It To C#


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 09 January 2012 - 04:43 PM

I'm working on a project that requires an array of textures. I'm looking to get the assets through PHP to avoid allowing direct access to them, but am having trouble getting them to return in a meaningful way. This is what I've built so far on the PHP side:

<?php
if(filter_has_var(INPUT_POST, "merchant") && filter_has_var(INPUT_POST, "test"))
{
$merchant = filter_input(INPUT_POST, "merchant", FILTER_SANITIZE_STRING);
$test = filter_input(INPUT_POST, "test", FILTER_SANITIZE_STRING);
}
else
{
die ("DataMissing");
}
$data_location = $_SERVER['DOCUMENT_ROOT'] . "/" . $merchant;
$arr = array();
if (is_dir($data_location))
{
    $dir = opendir($data_location) or die("Couldn't access directory!");
    while (($file = readdir($dir)) !== false)
    {
  $arr[] = file_get_contents($file);
    }
    echo $arr;
}
else
{
// Need to create it
mkdir($data_location, 0700) or die("Couldn't create " . $data_location);
echo "Empty";
}
?>

Creating the directory works fine, however I'm not seeming to get what I'd expect back to the C# program which calls it. In fact, with nothing in the folder, I seem to get back the string "Array". Needless to say, that's not what I expect or want!
My name is "Todd". Drop the "T" and it explains sooooooo much! :P

Sponsor:

#2 Deprecated   Members   -  Reputation: 107

Like
0Likes
Like

Posted 09 January 2012 - 05:00 PM

There is no to_str() method that will convert your array to readable data in PHP. If you want to display the content of an array (or any other object) you'll have to use print_r($mixed).

If you want your PHP script to output an image you could use the code below;
<?php
$file = 'creature.png';
header('Content-Type:image/png');
header('Content-Length: ' . filesize($file));
print(readfile($file))
?>

P.S It is very important that you do not output any kind of data (not even a newline, space or tab) anywhere else in the code. D.S
Those who can do, do; those who can't do, do teach.

#3 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 09 January 2012 - 05:07 PM

I may not have said it quite the way I intended. let me clarify a bit more. I'm utilizing the Unity 3D game engine and need to get the PNG files into PHP and returned to C# as a byte array. The reason for needing this format is I intend to utilize "Texture2D.LoadImage()" to take the byte data and convert it into a Texture2D for display in the game. Sorry about the confusion :)
My name is "Todd". Drop the "T" and it explains sooooooo much! :P

#4 Deprecated   Members   -  Reputation: 107

Like
0Likes
Like

Posted 09 January 2012 - 05:33 PM

Remember that your browser will interpret images and render them for you, instead of outputting the bytes they consist of. The code I posted will output the raw data from the image, meaning the bytes it consists of. I'm not sure whether or not C# Texture2D.LoadImage() accepts data containing the file-header, but unless you plan to output something that could be evaluated and parsed by C# I think you'll have to output the actual file.


$ lynx -source http://localhost:80/~username/gamedev.php
�PNG
▒
IHDR2?��	    pHYs���o�d
OiCCPPhotoshop ICC profilexڝSgTS�=���BK���Ko RB���&*!   J�!��Q�EE�
...

Those who can do, do; those who can't do, do teach.

#5 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 09 January 2012 - 05:37 PM

Excepting this has nothing to do with a browser :) I'm creating a PC/Mac standalone, not a web player application. Thus the need to figure out how to get a byte array to pass back to C# from PHP. It would be easy if "return" would actually work, but that doesn't seem to actually return anything to C#. Of course at the moment neither does the echo $arr :P
My name is "Todd". Drop the "T" and it explains sooooooo much! :P

#6 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 09 January 2012 - 05:53 PM

Okay, seems there's a gotcha I wasn't aware of. I haven't confirmed 100% that the above works, but I was able to confirm that part of the code results in a bit of an oddity.

while (($file = readdir($dir)) !== false)
{
$arr[] = file_get_contents($file);
}


Detects 3 files even though only one is in the folder. The other two filenames it picks up are "." and "..". Wrapping the the line to load the file inside

if($file != "." && $file != "..")


returns something that looks like it might be what I wanted. The size of the byte[] is about what I expected :)
My name is "Todd". Drop the "T" and it explains sooooooo much! :P

#7 Deprecated   Members   -  Reputation: 107

Like
0Likes
Like

Posted 09 January 2012 - 05:56 PM

You're not understanding me... The code I posted will output a sequence of data that represents the image. Below are some examples on how to work with the above example in python. Although I haven't tested the code, in the first example, bytestream should be accepted by SFML as an image in memory.

1. To read the data as a stream of bytes in python
import urllib.request
bytestream = urllib.request.urlopen('http://localhost:80/~username/gamedev.php')

2. To read the data as an array of bytes in python
import urllib.request
bytearray = [c for c in urllib.request.urlopen('http://localhost:80/~username/gamedev.php').read()]

3. To read the data as a stream of bytes and save it to file in python
import urllib.request
open('image.png', 'wb').write(urllib.request.urlopen('http://localhost:80/~username/gamedev.php').read())

Those who can do, do; those who can't do, do teach.

#8 Deprecated   Members   -  Reputation: 107

Like
0Likes
Like

Posted 09 January 2012 - 06:02 PM

Detects 3 files even though only one is in the folder. The other two filenames it picks up are "." and "..". Wrapping the the line to load the file inside


The symbolic links . and .. represents the current and the previous folder.

'C:\Program Files\.\.\.\..\Program Files\..' should place you in 'C:\', assuming that there is a directory called Program Files in your root.


Edit: Added the quote I was responding to.

Edited by Deprecated, 09 January 2012 - 06:04 PM.

Those who can do, do; those who can't do, do teach.

#9 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 09 January 2012 - 06:20 PM

Ah. That's much shorter than trying to echo it, and gets the same results. Unfortunately, the results still don't seem to want to load as an image. Then too, there's the matter of returning it as an array of images regardless. At least this gets a good start on tomorrow. Thanks for the assist, Deprecated.
My name is "Todd". Drop the "T" and it explains sooooooo much! :P

#10 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 10 January 2012 - 08:52 AM

Back to the problem early :) The size of the file is 4183 as reported by "filesize()" in PHP. Using Deprecated's suggestion of "print(readfile($data_location . "/" . $file));" returns a string to the C# script that's only 4040. Using my original method of "$arr[] = file_get_contents($data_location . "/" . $file);" and echoing element 0 (the one element in this test case), yields a string of size 4036. Can anyone explain why both of these are shorter than the number of bytes in the original file? I hadn't thought it would be so tricky to get a byte array into PHP and return it to the C# script that calls it, but that certainly seems to be the case.

Calling code and reporting result
   WWWForm form = new WWWForm();
   form.AddField("merchant", accountID);
   form.AddField("test", testMode);
  
   string result = sendData.StartSending(form, prepend + "get_images.php");
  
   Debug.Log(result.Length);

PHP Code
<?php
if(filter_has_var(INPUT_POST, "merchant") && filter_has_var(INPUT_POST, "test"))
{
$merchant = filter_input(INPUT_POST, "merchant", FILTER_SANITIZE_STRING);
$test = filter_input(INPUT_POST, "test", FILTER_SANITIZE_STRING);
}
else
{
die ("DataMissing");
}
$data_location = $_SERVER['DOCUMENT_ROOT'] . "/" . $merchant;
$arr = array();
if (is_dir($data_location))
{
    $dir = opendir($data_location) or die("Couldn't access directory!");
    while (($file = readdir($dir)) !== false)
    {
	 if($file != "." && $file != "..")
	 {
	  //print(readfile($data_location . "/" . $file));
	  $arr[] = file_get_contents($data_location . "/" . $file);
	 }
    }
   
echo $arr[0];
closedir();
}
else
{
// Need to create it
mkdir($data_location, 0700) or die("Couldn't create " . $data_location);
echo "Empty";
}
?>

My name is "Todd". Drop the "T" and it explains sooooooo much! :P

#11 Charabis   Members   -  Reputation: 123

Like
0Likes
Like

Posted 10 January 2012 - 09:49 AM

Okay, it turns out the problem wasn't in any of the code I posted. StartSending uses Unity's WWW object to communicate with the server. I was still using the version I was using to pass XML around (WWW.text), which is not advised for binary data. That's what "WWW.bytes" is for >.<
My name is "Todd". Drop the "T" and it explains sooooooo much! :P




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS