| View previous topic :: View next topic |
Brad Keys

Joined: 01 May 2006 Posts: 33 Location: Vancouver, Canada
|
Posted: Wed Oct 07, 2009 10:05 pm Post subject: Convert PNG to JPG without writing to disk |
|
|
|
Goal
I'm creating a feature that takes a screen capture of the Unity game and uploads it to my web server using the web player. I've got this working just fine.
Issue
The problem is that the files being uploaded are unnecessarily large (300KB+). I could do some image manipulation in PHP, but I'd like to stay away from having my server doing all that work. .Net has some functionality to convert images to other formats, but as far as I've seen those methods require you to write the newly converted image to disk... which I can't have happen since I'm wanting to do this in the web player.
Solution Needed
I need Unity to convert the PNG image to JPG format without writing to disk.
Any ideas on how I can achieve this? |
|
| Back to top |
|
|
SoarionStudios

Joined: 23 Apr 2009 Posts: 49 Location: Dallas, TX
|
Posted: Thu Oct 08, 2009 1:37 am Post subject: |
|
|
|
While technically, this is not really "the answer", I have "an answer"
If you look around on this forum thread: https://mollyrocket.com/forums/viewtopic.php?p=5898 then you can find code for a public domain JPG library as well as pointers to some PNG decompression source code. You could likely cobble those together to do what you need if you can port all that to C#... Or if you have the Advanced version, you could do it in native Obj-C or C++ and do it that way?
Stephen |
|
| Back to top |
|
|
Matthew

Joined: 30 Nov 2006 Posts: 1207 Location: Phoenix, AZ
|
Posted: Thu Oct 08, 2009 2:36 am Post subject: |
|
|
|
This should be fairly easy with .NET, but it looks like Unity's Mono environment is lacking the proper functionality.
This line:
| Code: |
var codecs:ImageCodecInfo[] = ImageCodecInfo.GetImageEncoders();
|
Produces:
| Code: |
DllNotFoundException: gdiplus.dll
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders ()
System.Drawing.GDIPlus..cctor ()
UnityEditor.EditorGUIUtility:RenderGameViewCameras(Rect, Rect, Boolean, Boolean)
UnityEditor.EditorGUIUtility:RenderGameViewCameras(Rect, Rect, Boolean, Boolean)
UnityEditor.GameView:OnGUI()
System.Reflection.MonoMethod:InternalInvoke(Object, Object[])
System.Reflection.MonoMethod:InternalInvoke(Object, Object[])
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
UnityEditor.HostView:Invoke(String)
UnityEditor.DockArea:OnGUI() |
I suppose you could find a totally exposed C# implementation of JPEG compression, but with functionality already present in .NET I doubt there's one out there... _________________ Matthew Wegner
Founder and CEO, Flashbang Studios / Blurst
Co-Chair, IGF
Editor, Fun-Motion |
|
| Back to top |
|
|
Brad Keys

Joined: 01 May 2006 Posts: 33 Location: Vancouver, Canada
|
Posted: Thu Oct 08, 2009 6:50 pm Post subject: |
|
|
|
| Matthew wrote: | | This should be fairly easy with .NET, but it looks like Unity's Mono environment is lacking the proper functionality. |
Ya, its turning out to be really inconvenient. Would it be worth me asking for a feature request? Or is this too obscure of a problem?
| Matthew wrote: | | I suppose you could find a totally exposed C# implementation of JPEG compression, but with functionality already present in .NET I doubt there's one out there... |
I doubt that too. I'll keep looking for a bit, but I'm afraid that for the time being I'll just have to handle the compression with PHP. |
|
| Back to top |
|
|
Matthew

Joined: 30 Nov 2006 Posts: 1207 Location: Phoenix, AZ
|
Posted: Thu Oct 08, 2009 7:23 pm Post subject: |
|
|
|
| Brad Keys wrote: | | Matthew wrote: | | This should be fairly easy with .NET, but it looks like Unity's Mono environment is lacking the proper functionality. |
Ya, its turning out to be really inconvenient. Would it be worth me asking for a feature request? Or is this too obscure of a problem?
|
It's worth requesting, at least. It might be something simple for Unity to add, although my guess is it's a deliberate feature reduction in order to save file size on the web player... _________________ Matthew Wegner
Founder and CEO, Flashbang Studios / Blurst
Co-Chair, IGF
Editor, Fun-Motion |
|
| Back to top |
|
|
Matthew

Joined: 30 Nov 2006 Posts: 1207 Location: Phoenix, AZ
|
|
| Back to top |
|
|
Brad Keys

Joined: 01 May 2006 Posts: 33 Location: Vancouver, Canada
|
Posted: Sun Nov 29, 2009 1:47 am Post subject: |
|
|
|
| Thanks, this will be extremely useful. |
|
| Back to top |
|
|
Brad Keys

Joined: 01 May 2006 Posts: 33 Location: Vancouver, Canada
|
Posted: Tue Dec 01, 2009 8:21 pm Post subject: |
|
|
|
I tried it out but I'm having some troubles. I'm trying to upload the image to my website, but the file type that's getting uploaded is returning as: application/octet-stream rather than image/jpeg. Here is my modified version of your example project.
| Code: |
function ScreenshotEncode()
{
// wait for graphics to render
yield WaitForEndOfFrame();
// create a texture to pass to encoding
var texture:Texture2D = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
// put buffer into texture
texture.ReadPixels(Rect(0.0, 0.0, Screen.width, Screen.height), 0.0, 0.0);
texture.Apply();
// split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
yield;
// create our encoder for this texture
var encoder:JPGEncoder = new JPGEncoder(texture, 75.0);
// encoder is threaded; wait for it to finish
while(!encoder.isDone)
yield;
// Create a Web Form
var form = new WWWForm();
form.AddBinaryData("avatar", encoder.GetBytes());
// Upload to PHP script
var w = WWW(screenShotURL, form);
yield w;
if (w.error != null) {
print(w.error);
}
else {
print(w.data);
}
} |
|
|
| Back to top |
|
|
Matthew

Joined: 30 Nov 2006 Posts: 1207 Location: Phoenix, AZ
|
Posted: Tue Dec 01, 2009 9:22 pm Post subject: |
|
|
|
This looks like a Unity thing:
| Code: |
If mimeType is not given and first 8 bytes of the data match PNG format header, then the data is sent with "image/png" mimetype. Otherwise it is sent with "application/octet-stream" mimetype.
|
The MIME type shouldn't matter too much, depending on what your server-side code looks like. Are you just saving to disk? _________________ Matthew Wegner
Founder and CEO, Flashbang Studios / Blurst
Co-Chair, IGF
Editor, Fun-Motion |
|
| Back to top |
|
|
Matthew

Joined: 30 Nov 2006 Posts: 1207 Location: Phoenix, AZ
|
Posted: Tue Dec 01, 2009 9:31 pm Post subject: |
|
|
|
Actually, based on the docs, just try:
| Code: |
form.AddBinaryData("avatar", encoder.GetBytes(), "screenshot.jpg", "image/jpeg");
|
_________________ Matthew Wegner
Founder and CEO, Flashbang Studios / Blurst
Co-Chair, IGF
Editor, Fun-Motion |
|
| Back to top |
|
|
Brad Keys

Joined: 01 May 2006 Posts: 33 Location: Vancouver, Canada
|
Posted: Tue Dec 01, 2009 9:42 pm Post subject: |
|
|
|
Ah, yes that did the trick. Works beautifully.
Thanks a lot. |
|
| Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
|