Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load .png image into object of Bitmap class? #12

Open
ArsenShnurkov opened this issue Feb 19, 2016 · 2 comments
Open

How to load .png image into object of Bitmap class? #12

ArsenShnurkov opened this issue Feb 19, 2016 · 2 comments

Comments

@ArsenShnurkov
Copy link

I want to avoid unmanaged code from libgdiplus and libpng in mono.

I.e. something like http://stackoverflow.com/a/6809677/1709408

public static void LoadThroughPngcs(this Bitmap bmp, string filename)
{
    if (bmp == null) throw new ArgumentNullException("bmp");
    // read bmpWidth, bmpHeight
    var data = bmp.LockBits(
        new Rectangle(0, 0, bmpWidth, bmpHeight),
        System.Drawing.Imaging.ImageLockMode.ReadWrite,
        System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    var line = data.Scan0;
    var eof = line + data.Height * data.Stride;
    while(line != eof)
    {
        var pixelAlpha = line + 3;
        var eol = pixelAlpha + data.Width * 4;
        while(pixelAlpha != eol)
        {
            System.Runtime.InteropServices.Marshal.WriteByte(
                pixelAlpha, alpha);
            pixelAlpha += 4;
        }
        line += data.Stride;
    }
    bmp.UnlockBits(data);
}

but with reading pixels through libcs

@ArsenShnurkov
Copy link
Author

May be something should have property of type IEnumerable<KeyValuePair<Point, Color> >. KeyValuePair instead of Pair, because the former is value type, and the later is reference type...

Or it is better to have a class which converts pixel sequential number into coordinates and vice versa.

@ArsenShnurkov
Copy link
Author

   public static Bitmap LoadPng(string fileName)
    {
        PngReader pngr = FileHelper.CreatePngReader(fileName);
        pngr.SetUnpackedMode(true);
        int channels = pngr.ImgInfo.Channels;
        int bmpWidth = pngr.ImgInfo.Cols;
        int bmpHeight = pngr.ImgInfo.Rows;
        Bitmap bmp = new Bitmap(bmpWidth, bmpHeight, PixelFormat.Format32bppArgb);
        int A = 255;
        for (int y = 0; y < bmpHeight; y++)
        {
            ImageLine line = pngr.ReadRowInt(y);
            for (int x = 0; x < bmpWidth; x++)
            {
                int startByte = x * channels;
                int R = line.Scanline[startByte + 0];
                int G = line.Scanline[startByte + 1];
                int B = line.Scanline[startByte + 2];
                if (channels == 4)
                {
                    A = line.Scanline[startByte + 3];
                }
                Color c = Color.FromArgb(A, R, G, B);
                bmp.SetPixel(x, y, c);
            }
        }
        return bmp;
    }

My picture have 3 channels. How to get global transparency info in pngcs?
PngChunkTRNS trns = pngr.GetMetadata().GetTRNS(); // transparency metadata, can be null

pngr.ImgInfo {ImageInfo [cols=16, rows=16, bitDepth=8, channels=3, bitspPixel=24, bytesPixel=3, bytesPerRow=48, samplesPerRow=48, samplesPerRowP=48, alpha=False, greyscale=False, indexed=False, packed=False]} Hjg.Pngcs.ImageInfo

pngr.GetMetadata().GetTRNS() {chunk id= tRNS (len=6 off=33) c=PngChunkTRNS} Hjg.Pngcs.Chunks.PngChunkTRNS

So, I receive image without transparency at the end (lose alpha value of image)
may be this will work, may be not:

var trns = pngr.GetMetadata ().GetTRNS ();
if (trns != null) {
    int[] rgb = trns.GetRGB ();
    var tc = Color.FromArgb (0, rgb [0], rgb [1], rgb [2]);
    bmp.MakeTransparent (tc);
}

kekekeks added a commit to kekekeks/pngcs that referenced this issue Nov 26, 2018
improve completion with resources, namespaces
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant