0

I am using the jQuery Webcam Plugin with this code:

$("#camera").webcam({
            width: 250,
            height: 375,
            mode: "save",
            /*swffile: "js/jscam_canvas_only.swf",*/
            swffile: "js/jscam.swf",
            onTick: function(remain) {
                if (0 == remain) {
                    jQuery("#status").text("Cheese!");
                } else {
                    jQuery("#status").text(remain + " seconds remaining...");
                }
            },
            onSave: function () { },
            onCapture: function () {
                webcam.save('/upload.ashx');
            },
            debug: function () { },
            onLoad: function () { }
        });

The plugin uses PHP like this:

<?php
    $str = file_get_contents("php://input");
    file_put_contents("/tmp/upload.jpg", pack("H*", $str));
?>

and my upload.ashx :

public void ProcessRequest(HttpContext context)
{
    System.IO.Stream str = context.Request.InputStream;
    int strLen = Convert.ToInt32(str.Length);
    byte[] strArr = new byte[strLen];
    str.Read(strArr, 0, strLen);

    //string st = BitConverter.ToString(strArr); // try 1
    //string st = BitConverter.ToString(strArr).Replace("-",""); // try 2
    //string st = ByteArrayToString(strArr); //try 3
    string st = String.Concat(Array.ConvertAll(strArr, x => x.ToString("X2"))); // try 4
    File.WriteAllText(context.Server.MapPath("~/img/Webcam" + DateTime.Now.Ticks.ToString() + ".jpg"), st);
}

public static string ByteArrayToString(byte[] ba)
{
    StringBuilder hex = new StringBuilder(ba.Length * 2);
    foreach (byte b in ba)
        hex.AppendFormat("{0:x2}", b);
    return hex.ToString();
}

I also tried to read the byte array to the Bitmap object and save that to the disk, but that also does not work. I am really missing something here...

Edit Thanks Onkelborg,

I forgot to mention that the code does not give errors, it saves files. But the images are corrupted. Can't view them in Windows Photo Viewer or Adobe Photoshop.

Edit2 this also does not work. (also corrupt images) Save Image From Webrequest in C#

Edit3 I use this to convert the string to high nibble first hex:

    public static byte[] ToHexByte(byte[] arstr)
    {
        byte[] data = new byte[arstr.Length];
        int end = arstr.Length;

        for (int i = 0; i < end; i++)
        {
            byte ch = arstr[i];
            byte highNibble = (byte)((ch & 0xf0) >> 4);
            byte lowNibble = (byte)((ch & 0x0f) << 4);
            data[i] = (byte)(highNibble | lowNibble);
        }
        return data;
    }

Edit4

I found this resource http://www.kirupa.com/forum/showthread.php?300792-XML.sendAndLoad%28%29-not-working-IIS7.-ASP.Net-2.0-%28C-3.0%29 and set ValidateRequest="false" in my page directive. found that because i found line 183 from https://github.com/infusion/jQuery-webcam/blob/master/src/jscam.as i have the feeling that i am getting closer now.

Community
  • 1
  • 1
JP Hellemons
  • 5,977
  • 11
  • 63
  • 128

2 Answers2

1

The first, and biggest, problem is the fact that you try to convert from bytes to strings, that's wrong. You should save those bytes directly without "converting" them in any way.

The next problem is that you are reading your stream in the wrong way. See: How do I copy the contents of one stream to another?

Community
  • 1
  • 1
Onkelborg
  • 3,927
  • 1
  • 19
  • 22
  • so this would be sufficient: byte[] data = Request.BinaryRead(Request.TotalBytes); File.WriteAllBytes(Server.MapPath("img/" + DateTime.Now.ToString("dd_MMM_yymmss") + ".jpg"), data); – JP Hellemons Nov 25 '11 at 11:24
  • I don't know exactly how BinaryRead works, but it sounds like it should work – Onkelborg Nov 25 '11 at 11:48
  • Hi Onkelborg, The PHP function converts it to hex with high nibble first http://php.net/manual/en/function.pack.php so I have to make my C# code act like the PHP code – JP Hellemons Nov 25 '11 at 14:46
  • Have you tried without messing with strings? (I promise, you don't want your image converted to a string. It just don't work. PHP, and ASP/VB6, treat binary data and strings the same, for some reason.) However, the case might be that the flash-file uploads the image as a base 16-encoded string, and that the pack-function takes the string a converters it into binary. Maybe that's what you have to do. See: http://stackoverflow.com/questions/2972103/how-to-convert-a-string-to-a-hex-byte-array – Onkelborg Nov 25 '11 at 15:14
  • Hi Onkelborg, the flash seems to encode a jpg and send it as xml. I found that on https://github.com/infusion/jQuery-webcam/blob/master/src/jscam.as i am trying to extract and save the jpg now. – JP Hellemons Nov 28 '11 at 10:16
  • I would recommend you to just save the image to a file first, and then examine the content of the file. And no, the flash does not seem to send xml. – Onkelborg Nov 28 '11 at 16:22
  • You need to teach yourself how to learn yourself how to program. (Strang sentence, I know..) As far as I can tell, you're not a experienced programmer in any way. You need to learn a few, basic things about programming: A) Read B) Try C) Ask D) Examine the answers you get E) Reply with new info about your progress (did it work? If not, what went wrong?) For example, I don't know if you have tried my suggestions, and if you did, what's the result? Working? Exceptions? Wrong result? And if you didn't try, why are you asking? – Onkelborg Nov 28 '11 at 16:32
  • Lol! I read the whole actionscript code from the swf and tried so much to save a valid jpg, but didn't work. That's why I asked a question here. In fact, no one has got this to work with asp.net. everybody moved to an other plugin! – JP Hellemons Nov 30 '11 at 10:06
  • Have you read what I just wrote? Your feedback is nonexistent. Of course it's impossible to come up with a solution to your problem then.. – Onkelborg Nov 30 '11 at 10:28
1

The answer is: http://code.google.com/p/jpegcam/ because it is hard to find out how to decode the bytes you receive from the flash file.

Now I just needed two lines of Asp.Net C# code in my *.ashx file:

byte[] data = context.Request.BinaryRead(context.Request.TotalBytes);

File.WriteAllBytes(context.Server.MapPath("~/img/cam" + DateTime.Now.Ticks + ".jpg"), data);
JP Hellemons
  • 5,977
  • 11
  • 63
  • 128