-1

I am trying to write a method that takes image data in base64 string and saves it into a binary file while preserving transparency (for example in case of PNGs).

My other requirement is that this needs to be done in C# in PCL (Portable Class Library).

I know that you can use Image or WriteableBitmap to solve this issue but such classes are not available in PCL.

I have the following method that does the job of taking the base64 data and saving it to a file:

public static async Task Base64ToBinaryImageFile(IFile file, string base64Content)
{
    var bytes = Convert.FromBase64String(base64Content);
    using (var stream = await file.OpenAsync(FileAccess.ReadAndWrite))
    {
        stream.Seek(0, SeekOrigin.Begin);
        using (var writer = new BinaryWriter(stream))
        {
            writer.Write(content);
            writer.Flush();
        }
    }
}

It works fine except that:

  1. I lose the transparency data (so transparent pixels show up as black).

  2. The file that is created using this method has a larger size (in bytes) than the original file.

Any idea on what's the cause and how to fix these issues?


Update: Here is the JavaScript code that sends the base64 data to C#:

function onPaste(event) {
    var $event = event.data.$;
    var clipboardData = $event.clipboardData;
    var found = false;
    var imageType = /^image/;
    if (!clipboardData) {
        return false;
    }

    return Array.prototype.forEach.call(clipboardData.types, function (type, i) {
        if (found) {
            return false;
        }

        if (type.match(imageType) || clipboardData.items[i].type.match(imageType)) {
            readImageAsBase64(clipboardData.items[i]);
            return found = true;
        }

        return false;
    });
}

function readImageAsBase64(item) {
    if (!item || typeof item.getAsFile !== "function") {
        return;
    }

    var file = item.getAsFile();
    var reader = new FileReader();

    reader.onload = function (evt) {
        window.external.notify("pasteImageBase64/" + evt.target.result);
    };

    reader.readAsDataURL(file);
}
  • 4
    This code does nothing to the image data except save it into a file. If the image data isn't what you wanted, the stuff in `base64Content` is already wrong. Where does the base64 encoded data come from? Perhaps a copied and pasted image from a browser..? – Matti Virkkunen Aug 18 '16 at 19:02
  • 1
    Can you post the code that makes the base64 string? – R.Rusev Aug 18 '16 at 19:02
  • 1
    I suspect the loss happens when creating the base64Content string – matt-dot-net Aug 18 '16 at 19:04
  • @Matti Virkkunen: Basically I have a WebView control that is hosting HTML content with JS. When a copy-paste action occurs inside the HTML page, the JS kicks in and looks at the content to be pasted. If it is an image then JS will read the content of the clipboard and pass it to C# code for further processing. I wanted to simply save the content first to make sure I am correctly sending the data from JS to C# code behind before taking it further. Like I said it works for all images that do not have transparency (even PNG with no transparency). I've updated the original question with JS code. – Meisam Seyed Aliroteh Aug 19 '16 at 23:13
  • That would be the web view not supporting pasting transparent images then. It's a known limitation in webkit at least as far as I can remember. There isn't much you can do about it. – Matti Virkkunen Aug 22 '16 at 11:26

1 Answers1

0

I foresee a few possible issues:

  1. Your issue could reside in the base64Content provided by the caller. It's possible that the conversion to base64Content that is provided as input to your method is reading the PNG image with an incorrect file format.

  2. Related to #1, it's possible that someone calling the method took a .JPG or .BMP image file, naively renamed it to .PNG extension and called your method assuming that they were sending a PNG image, when in fact they were not.

  3. You may be opening the .PNG image in testing with an image viewer/editor that does not support transparency or handle it well (IE mspaint.exe)

ravibhagw
  • 1,740
  • 17
  • 28
  • See comments above RE how the base64Content is set. As for #2 & #3 above, the original image is a valid PNG image with some transparent pixels (verified using Paint.Net and Photoshop). After the image is saved using my method the transparent pixels are lost (again verified using Paint.Net and Photoshop) – Meisam Seyed Aliroteh Aug 19 '16 at 23:20