1

I am trying to replace an Image in my View by a click. My controller returns an byte Array but the View replaces the original image with an empty one.

Here is my Controller code:

        [HttpPost]
    public byte[] GetSelectedImage(string selectedImageId, string accountId, string courseId)
    {
        // Laden des Originalfotos
        var pictures = (from ga in _db.MyPhotos
                        where
                            ga.AccountId.Equals(accountId) &&
                            ga.CourseId.Equals(courseId) &&
                            ga.SortOrder.Equals(selectedImageId)
                        select ga.PhotoStreamOriginal.ToArray());
        var images = pictures.ToList();


        byte[] imageByteArray = images.First();
        return imageByteArray;
    }

And hier is what I am doing in my Javascript:

     $('#makeMeScrollable img').live('click touchstart', function (event) {
        event.preventDefault();
        var selectedImage = $(this).attr('data-id');

        var selectedImageId = @Html.Raw(Json.Encode(Model.SelectedImageId));
        var accountId = @Html.Raw(Json.Encode(Model.AccountId));
        var courseId = @Html.Raw(Json.Encode(Model.CourseId));

        $.ajax({
            url: '@Url.Action("GetSelectedImage", "UploadPhoto")',
            dataType: 'text',
            data: {selectedImageId: selectedImageId, accountId: accountId, courseId: courseId},
            type: 'POST',
            success: function(data) {
                $('#OriginalImage').attr('src', "data:image/jpg;base64," + data);
                alert("data:image/jpg;base64," + data);
            }
        });
    });

The alert also shot only, data:image/jpg;base64,System.Byte[]

Any idea what I am doing wrong?

Thanks for you help

user2286914
  • 57
  • 2
  • 5

3 Answers3

1

This allows you to just get the image data and set to the img src, which is cool.

var oReq = new XMLHttpRequest();
oReq.open("post", '/somelocation/getmypic', true );        
oReq.responseType = "blob";
oReq.onload = function ( oEvent )
{
    var blob = oReq.response;
    var imgSrc = URL.createObjectURL( blob );                        
    var $img = $( '<img/>', {                
        "alt": "test image",
        "src": imgSrc
    } ).appendTo( $( '#bb_theImageContainer' ) );
    window.URL.revokeObjectURL( imgSrc );
};
oReq.send( null );

The basic idea is that the data is returned untampered with, it is placed in a blob and then a url is created to that object in memory. See here and here. Note supported browsers.

Community
  • 1
  • 1
acarlon
  • 16,764
  • 7
  • 75
  • 94
0

Instead of returning a byte array you need to return the base64 string, like this:

[HttpPost]
public string GetSelectedImage(string selectedImageId, string accountId, string courseId)
    {
        // Laden des Originalfotos
        var pictures = (from ga in _db.MyPhotos
                        where
                            ga.AccountId.Equals(accountId) &&
                            ga.CourseId.Equals(courseId) &&
                            ga.SortOrder.Equals(selectedImageId)
                        select ga.PhotoStreamOriginal.ToArray());
        var images = pictures.ToList();


        byte[] imageByteArray = images.First();
        return Convert.ToBase64String(imageByteArray);
    }

Checkout this article it shows you the full process http://www.codeproject.com/Articles/201767/Load-Base64-Images-using-jQuery-and-MVC

Stefan P.
  • 9,489
  • 6
  • 29
  • 43
0

If you're using MVC4, you may want to go one step further and cut out all the base 64 conversion. You can use the FileStreamResult to good effect, simply dynamically set the img src to the controller action (use the route values in Url.Action), something like the following (you will need to edit, I can't test for accuracy, but it should give you a good idea):

 $('#makeMeScrollable img').live('click touchstart', function (event) {
    event.preventDefault();
    var selectedImage = $(this).attr('data-id');

    var selectedImageId = @Html.Raw(Json.Encode(Model.SelectedImageId));
    var accountId = @Html.Raw(Json.Encode(Model.AccountId));
    var courseId = @Html.Raw(Json.Encode(Model.CourseId));

    $('#OriginalImage').attr('src', @Url.Action("GetSelectedImage", "UploadPhoto", new { selectedImageId = selectedImageId, etc }));

    // no need for this
    //$.ajax({
    //    url: '@Url.Action("GetSelectedImage", "UploadPhoto")',
    //    dataType: 'text',
    //    data: {selectedImageId: selectedImageId, accountId: accountId, courseId: courseId},
    //    type: 'POST',
    //    success: function(data) {
    //        $('#OriginalImage').attr('src', "data:image/jpg;base64," + data);
    //        alert("data:image/jpg;base64," + data);
    //    }
    });
});

[HttpGet]
public ActionResult GetSelectedImage(string selectedImageId, string accountId, string courseId)
{
    // Laden des Originalfotos
    var pictures = (from ga in _db.MyPhotos
                    where
                        ga.AccountId.Equals(accountId) &&
                        ga.CourseId.Equals(courseId) &&
                        ga.SortOrder.Equals(selectedImageId)
                    select ga.PhotoStreamOriginal.ToArray());
    var images = pictures.ToList();


    byte[] imageByteArray = images.First();
    return base.File(imageByteArray, "image/jpg");
}

Note, you'll also need to set up a route to route the request to the correct action but that should be easy enough to figure out...

SteveChapman
  • 3,051
  • 1
  • 22
  • 37