Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Level 9

Re: BuhByteArray

at this point, 360 x 360 seems to be the limit. KC, Mark - is there a limit to the string size the Roku will output? I say this because it takes several seconds for URL transfer to send the file (roku3) but the server builds 360x360 immediately, and won't do anything at 370x370. There are no size limits in the PHP file and I've upped the server limits for time and memory way beyond what is needed.
Kinetics Screensavers
0 Kudos
Highlighted
Level 8

Re: BuhByteArray

Just a thought ... instead of using all that encoding and decoding and bases and hexes and stuff, could you just write your roByteArray to a tmp file using ifByteArray.WriteFile, then send the file to your server using ifUrlTransfer.AsyncPostFromFile?

Then your server can read all the bits and bytes from the file without having to decode anything:

<?php
$in = fopen('php://input', 'r');
$out = fopen('outfile', 'w');
stream_copy_to_stream($in, $out);
?>
https://github.com/belltown/
0 Kudos
Highlighted
Level 9

Re: BuhByteArray

"belltown" wrote:
Just a thought ... instead of using all that encoding and decoding and bases and hexes and stuff, could you just write your roByteArray to a tmp file using ifByteArray.WriteFile, then send the file to your server using ifUrlTransfer.AsyncPostFromFile?

That seems like a good idea that I can get to later once I can write the whole file - One problem is I actually know very little about PHP ( i just had to look up stream_copy_to_stream, as i did with imagesetpixel when KC mentioned it), although I've used it for years on my website, so if i get something working there is usually another big problem to deal with rather then optimizing as I go along, which is certainly the case here. This is the script thats building the jpeg from the POST data which I cobbled together from different examples and some guessing.
      $data = $_POST['subject'];
$owner = $_GET['owner'];
$sizex = $_GET['sizew'];
$sizey = $_GET['sizeh'];
$hexcolors = str_split ( $data, 8 ); //for hex string roku output
$file_name= $owner.".jpg";
$im = imagecreatetruecolor($sizex, $sizey);
$i=0;
$y=0;
while($y < $sizey) {
$x=0;
while($x < $sizex) {
$color = $hexcolors[$i];
$thiscolor= imagecolorallocate($im, hexdec(substr($color,0,2)), hexdec(substr($color,2,2)), hexdec(substr($color,4,2)));
imagesetpixel($im, $x,$y, $thiscolor);
$i++;
$x++;
}
$y++;
}
imagejpeg($im, $file_name);
imagedestroy($im);
One thing about the whole decoding thing, when i started this I first printed the bytearray as an ascii string to the console, and it didnt even look like a recognizeable anything - question marks and space was all I saw, probably doing something wrong, but at least hex values make sense to me and as you see above easily decoded, maybe easier then if i had the separate RGB values to deal with?
Kinetics Screensavers
0 Kudos
Highlighted
Level 8

Re: BuhByteArray

I was able to create a 720x480 byte array containing a bitmap of the French flag, send the byte array to my server, which in turn converted it to a jpg file, which I then displayed on my screen.

Here's the PHP code:

<?php
$owner = $_GET['owner'];
$sizex = $_GET['sizew'];
$sizey = $_GET['sizeh'];

$file_name = "$owner.jpg";

$in = fopen('php://input', 'r');

$im = imagecreatetruecolor($sizex, $sizey);

$y=0;
while($y < $sizey) {
$x=0;
while($x < $sizex) {
$thiscolor = imagecolorallocate($im, ord (fgetc ($in)), ord (fgetc ($in)), ord (fgetc ($in)));
imagesetpixel($im, $x, $y, $thiscolor);
fgetc ($in);
$x++;
}
$y++;
}
imagejpeg($im, $file_name);
imagedestroy($im);
?>


And the BrightScript code:

Sub Main ()
width = 720
height = 480
owner = "sqwiril"

' Make an image of the French flag and convert to an roByteArray
byteArray = MakeByteArray (width, height)

' Send the byte array to the server for conversion to a jpg file
Convert (byteArray, owner, width, height)

' Display the image
Display (owner)
End Sub

Function MakeByteArray (width As Integer, height As Integer) As Object
byteArray = CreateObject ("roByteArray")
byteArray.SetResize (width * height * 4, False)
i = 0
For x = 0 To height - 1
For y = 0 To width - 1
If y < CInt (width / 3)
r = 0 : g = 0 : b = 255 : a = 255
Else If y < CInt (width * 2 / 3)
r = 255 : g = 255 : b = 255 : a = 255
Else
r = 255 : g = 0 : b = 0 : a = 255
EndIf
byteArray [i + 0] = r
byteArray [i + 1] = g
byteArray [i + 2] = b
byteArray [i + 3] = a
i = i + 4
End For
End For
Return byteArray
End Function

Function Convert (byteArray As Object, owner As String, width As Integer, height As Integer) As Void
' Convert the byte array to a file
byteArray.WriteFile ("tmp:/byteArray")

' Send file to server
ut = CreateObject ("roUrlTransfer")
port = CreateObject ("roMessagePort")
ut.SetPort (port)
ut.SetUrl ("http://belltown.tk/bigimage.php?owner=" + owner + "&sizew=" + width.ToStr () + "&sizeh=" + height.ToStr ())
If Not ut.AsyncPostFromFile ("tmp:/byteArray")
Print "AsyncPostFromFile failed"
Stop
EndIf

msg = Wait (0, port)
If msg = Invalid
Print "Image upload timed out"
Stop
Else If Type (msg) <> "roUrlEvent"
Print "Unknown event"
Stop
Else If msg.GetResponseCode () <> 200
Print "Http Failure"; msg.GetResponseCode ()
Stop
Else
Print "File upload successful"
EndIf
End Function

Function Display (owner As String) As Void
url = "http://belltown.tk/" + owner + ".jpg"
ui = CreateObject ("roImageCanvas")
port = CreateObject ("roMessagePort")
ui.SetMessagePort (port)
ui.SetRequireAllImagesToDraw (True)
ui.SetLayer (0, {Url: url})
ui.Show ()
Wait (0, port)
End Function
https://github.com/belltown/
0 Kudos
Highlighted
Level 8

Re: BuhByteArray

It's even easier if you have ImageMagick installed on your server. Just use this script:

<?php
$owner = $_GET['owner'];
$sizex = $_GET['sizew'];
$sizey = $_GET['sizeh'];

$in = fopen('php://input', 'r');
$out = fopen("$owner.rgba", 'w');
stream_copy_to_stream($in, $out);

exec("convert -size {$sizex}x{$sizey} -depth 8 $owner.rgba $owner.jpg");

@unlink ("$owner.rgba");
?>


I also tried it with a 1280x720 image -- and did a base64 encode/decode to make the transfer size smaller. That worked as well, although it can take a while to upload a bitmap that large depending on your internet connection speed.
https://github.com/belltown/
0 Kudos
Highlighted
Level 9

Re: BuhByteArray

Vive La belltown! (sorry if that should be a le not la, my french is worse than my php) Thanks for all that. I just got it to work - very good lesson here about error handling. Because you are a professional and I only play one on TV, you did the thing pros do which is to put error handling into the URLtransfer thingie which allowed me to see i was getting a 413 error ( which may have been the problem yesterday) and so i was able to contact the server folks and they just yelled at the hamster on my server rack and fixed it, so now i see the 'tricolour' on my TV. Also thanks for the ImageMajik code, i do have that installed and will be using it to profile the image when i get to that part. Thanks again for your help.
Kinetics Screensavers
0 Kudos
Highlighted
Level 9

Re: BuhByteArray

Ok one last thing - that Imagemajik code - WoW! that produced a way way way better file - 650kb vs 120kb and no jpeg-ing artifacts. What a difference.
Kinetics Screensavers
0 Kudos
Highlighted
Level 7

Re: BuhByteArray

imagejpeg has an optional third parameter to specify the image quality. Tweaking that value might give similar results to imagemagick, though of course no reason to do that if you're happy with the current implementation.

--Mark
0 Kudos
Highlighted
Level 9

Re: BuhByteArray

"RokuMarkn" wrote:
imagejpeg has an optional third parameter to specify the image quality. Tweaking that value might give similar results to imagemagick, though of course no reason to do that if you're happy with the current implementation.

--Mark

Yea, plus Imagmajik has two things which are pretty much necessary - color profiling and bluring to de-jaggie the image.

Also I tried using base64 and it was NOT a help, it consistently took maybe 15% longer to send the string on my test image. It would make sense since the hex string always uses 8 characters to describe a pixel, the base64 sometimes uses only 4, but more often than not uses 10.

Either way if Roku would like to add the ability to at least URLtransfer a bitmap thats - you know - already created - i won't stop them.
Kinetics Screensavers
0 Kudos
Highlighted
Level 9

Re: BuhByteArray

"squirreltown" wrote:
Either way if Roku would like to add the ability to at least URLtransfer a bitmap thats - you know - already created - i won't stop them.

I'd prefer, and have requested multiple times, the ability to create a PNG on the device from an roBitmap. The libraries are already there, so it shouldn't require a major update, but to date, it doesn't seem to have gained any traction.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos