示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="clrMismatch"></param>
        /// <returns></returns>
        public unsafe bool CheckColorsMatch(out Color clrMismatch)
        {
            // Lock down bits for speed
            Rectangle  rc     = new Rectangle(0, 0, m_bm.Width, m_bm.Height);
            BitmapData bmd    = m_bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            byte *     pbBase = (byte *)bmd.Scan0.ToPointer();

            // Make sure each pixel is an exact match
            clrMismatch = Color.FromArgb(0, 0, 0);
            for (int y = 0; y < m_bm.Height; y++)
            {
                for (int x = 0; x < m_bm.Width; x++)
                {
                    byte *pb  = pbBase + y * bmd.Stride + x * 3;
                    Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);
                    if (m_pal[m_pal.FindClosestEntry(clr)] != clr)
                    {
                        m_bm.UnlockBits(bmd);
                        clrMismatch = clr;
                        return(false);
                    }
                }
            }
            m_bm.UnlockBits(bmd);
            return(true);
        }
示例#2
0
        public static Bitmap ScaleBitmap(Bitmap bm, double nScale, Palette palFixed)
        {
            Color[] aclrSpecial = new Color[] {
                // side colors
                Color.FromArgb(0, 116, 232),
                Color.FromArgb(0, 96, 196),
                Color.FromArgb(0, 64, 120),
                Color.FromArgb(0, 48, 92),
                Color.FromArgb(0, 32, 64),
                // transparent
                Color.FromArgb(255, 0, 255),
                // shadow
                Color.FromArgb(156, 212, 248),
            };

            Bitmap bmNew = new Bitmap((int)Math.Floor(bm.Width * nScale + 0.5), (int)Math.Floor(bm.Height * nScale + 0.5));

            for (int y = 0; y < bmNew.Height; y++)
            {
                for (int x = 0; x < bmNew.Width; x++)
                {
                    double nWidthRatio  = (double)bm.Width / (double)bmNew.Width;
                    double xLeft        = (double)x * nWidthRatio;
                    double nHeightRatio = (double)bm.Height / (double)bmNew.Height;
                    double yTop         = (double)y * nHeightRatio;
                    double xRight       = xLeft + 1.0 * nWidthRatio;
                    if (xRight > bm.Width)
                    {
                        xRight = bm.Width;
                    }
                    double yBottom = yTop + 1.0 * nHeightRatio;
                    if (yBottom > bm.Height)
                    {
                        yBottom = bm.Height;
                    }
                    DoubleRect drc       = new DoubleRect(xLeft, yTop, xRight, yBottom);
                    Color      clrSample = SampleGobBitmap(bm, drc, aclrSpecial, 4);
                    if (palFixed != null)
                    {
                        bool fSpecial = false;
                        foreach (Color clrSpecial in aclrSpecial)
                        {
                            if (clrSample == clrSpecial)
                            {
                                fSpecial = true;
                                break;
                            }
                        }
                        if (!fSpecial)
                        {
                            clrSample = palFixed[palFixed.FindClosestEntry(clrSample)];
                        }
                    }

                    bmNew.SetPixel(x, y, clrSample);
                }
            }

            return(bmNew);
        }
示例#3
0
        public static unsafe void Save(string strFile, Palette pal, string strFileOut)
        {
            Bitmap bm = new Bitmap(strFile);

            // Find the palette index for black
            int iclrBlack = pal.FindClosestEntry(Color.FromArgb(0, 0, 0));

            // Lock down bits for speed
            Rectangle  rc     = new Rectangle(0, 0, bm.Width, bm.Height);
            BitmapData bmd    = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            byte *     pbBase = (byte *)bmd.Scan0.ToPointer();

            // Map all the pixels in the bitmap to 'nearest' color palette indices
            byte[] ab = new byte[((bm.Width + 1) & ~1) * bm.Height];
            int    i  = 0;

            for (int y = 0; y < bm.Height; y++)
            {
                for (int x = 0; x < bm.Width; x++)
                {
                    byte *pb  = pbBase + y * bmd.Stride + x * 3;
                    Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);
                    if (clr == Color.FromArgb(156, 212, 248))
                    {
                        clr = Color.FromArgb(0, 0, 0);
                    }
                    ab[i++] = (byte)pal.FindClosestEntry(clr);
                }
                if ((bm.Width & 1) == 1)
                {
                    ab[i++] = (byte)iclrBlack;
                }
            }
            bm.UnlockBits(bmd);

            // Write bitmap header, bits
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFileOut, FileMode.Create, FileAccess.Write));

            bwtr.Write(Misc.SwapUShort((ushort)((bm.Width + 1) & ~1)));
            bwtr.Write(Misc.SwapUShort((ushort)bm.Height));
            bwtr.Write(ab);
            bwtr.Close();

            // Done
            bm.Dispose();
        }
示例#4
0
        public static unsafe void Save(string strFile, Palette pal, string strFileOut)
        {
            Bitmap bm = new Bitmap(strFile);

            // Find the palette index for black
            int iclrBlack = pal.FindClosestEntry(Color.FromArgb(0, 0, 0));

            // Lock down bits for speed
            Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
            BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            byte *pbBase = (byte *)bmd.Scan0.ToPointer();

            // Map all the pixels in the bitmap to 'nearest' color palette indices
            byte[] ab = new byte[((bm.Width + 1) & ~1) * bm.Height];
            int i = 0;
            for (int y = 0; y < bm.Height; y++) {
                for (int x = 0; x < bm.Width; x++) {
                    byte *pb = pbBase + y * bmd.Stride + x * 3;
                    Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);
                    if (clr == Color.FromArgb(156, 212, 248))
                        clr = Color.FromArgb(0, 0, 0);
                    ab[i++] = (byte)pal.FindClosestEntry(clr);
                }
                if ((bm.Width & 1) == 1)
                    ab[i++] = (byte)iclrBlack;
            }
            bm.UnlockBits(bmd);

            // Write bitmap header, bits
            BinaryWriter bwtr = new BinaryWriter(new FileStream(strFileOut, FileMode.Create, FileAccess.Write));
            bwtr.Write(Misc.SwapUShort((ushort)((bm.Width + 1) & ~1)));
            bwtr.Write(Misc.SwapUShort((ushort)bm.Height));
            bwtr.Write(ab);
            bwtr.Close();

            // Done
            bm.Dispose();
        }
        public static Bitmap ScaleBitmap(Bitmap bm, double nScale, Palette palFixed)
        {
            Color[] aclrSpecial = new Color[] {
                // side colors
                Color.FromArgb(0, 116, 232),
                Color.FromArgb(0, 96, 196),
                Color.FromArgb(0, 64, 120),
                Color.FromArgb(0, 48, 92),
                Color.FromArgb(0, 32, 64),
                // transparent
                Color.FromArgb(255, 0, 255),
                // shadow
                Color.FromArgb(156, 212, 248),
            };

            Bitmap bmNew = new Bitmap((int)Math.Floor(bm.Width * nScale + 0.5), (int)Math.Floor(bm.Height * nScale + 0.5));
            for (int y = 0; y < bmNew.Height; y++) {
                for (int x = 0; x < bmNew.Width; x++) {
                    double nWidthRatio = (double)bm.Width / (double)bmNew.Width;
                    double xLeft = (double)x * nWidthRatio;
                    double nHeightRatio = (double)bm.Height / (double)bmNew.Height;
                    double yTop = (double)y * nHeightRatio;
                    double xRight = xLeft + 1.0 * nWidthRatio;
                    if (xRight > bm.Width)
                        xRight = bm.Width;
                    double yBottom = yTop + 1.0 * nHeightRatio;
                    if (yBottom > bm.Height)
                        yBottom = bm.Height;
                    DoubleRect drc = new DoubleRect(xLeft, yTop, xRight, yBottom);
                    Color clrSample = SampleGobBitmap(bm, drc, aclrSpecial, 4);
                    if (palFixed != null) {
                        bool fSpecial = false;
                        foreach (Color clrSpecial in aclrSpecial) {
                            if (clrSample == clrSpecial) {
                                fSpecial = true;
                                break;
                            }
                        }
                        if (!fSpecial)
                            clrSample = palFixed[palFixed.FindClosestEntry(clrSample)];
                    }

                    bmNew.SetPixel(x, y, clrSample);
                }
            }

            return bmNew;
        }
示例#6
0
        static unsafe void Main(string[] args)
        {
            // Get parameters
            Palette palIn = new Palette(args[0]);
            string strFileOut = args[1];
            double dAlpha = Double.Parse(args[2]);

            // Create mapping
            byte[] ab = new byte[palIn.Length];
            Palette palInHSB = new Palette(palIn.Length);
            for (int iclr = 0; iclr < palIn.Length; iclr++) {
                Color clr = palIn[iclr];
                double h = clr.GetHue();
                double s = clr.GetSaturation();
                double l = clr.GetBrightness();
                double r;
                double g;
                double b;
                MyHSLtoRGB(h, s, l * dAlpha, &r, &g, &b);
                Color clrShadow = Color.FromArgb((int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
                ab[iclr] = (byte)palIn.FindClosestEntry(clrShadow);
            }

            // Write palette mapping
            Stream stm = new FileStream(strFileOut, FileMode.Create, FileAccess.Write, FileShare.None);
            BinaryWriter bwtr = new BinaryWriter(stm);
            bwtr.Write(ab);
            bwtr.Close();

            #if false
            // Check it
            Palette palCheck = new Palette(palIn.Length);
            for (int iclr = 0; iclr < palIn.Length; iclr++)
                palCheck[iclr] = palIn[ab[iclr]];
            palCheck.SaveJasc("shadow.pal");
            #endif
        }
 public void SetPalette(Palette pal, bool fColorMatch)
 {
     m_pal = pal;
     SetModified(true);
     if (!fColorMatch)
         return;
     ArrayList alsColors = new ArrayList();
     foreach (Template tmpl in m_alsTemplates) {
         Bitmap bm = tmpl.Bitmap;
         bool[,] afOccupancy = tmpl.OccupancyMap;
         int ctx = afOccupancy.GetLength(1);
         int cty = afOccupancy.GetLength(0);
         for (int ty = 0; ty < cty; ty++) {
             for (int tx = 0; tx < ctx; tx++) {
                 if (!afOccupancy[ty, tx])
                     continue;
                 int xOrigin = tx * m_sizTile.Width;
                 int yOrigin = ty * m_sizTile.Height;
                 for (int y = yOrigin; y < yOrigin + m_sizTile.Height; y++) {
                     for (int x = xOrigin; x < xOrigin + m_sizTile.Width; x++) {
                         Color clrOld = bm.GetPixel(x, y);
                         Color clrNew = pal[pal.FindClosestEntry(clrOld)];
                         bm.SetPixel(x, y, clrNew);
                     }
                 }
             }
         }
         TemplateDocTemplate doct = (TemplateDocTemplate)m_doct;
         doct.OnTemplateChanged(this, "Bitmap", tmpl.Name, null);
     }
 }
        void WriteMiniTiles(BinaryWriter bwtr, Palette pal, TemplateDoc tmpd, int cx, bool fNext, double nAreaBackgroundThreshold, double nLuminanceMultBackground, double nSaturationMultBackground, double nLuminanceMultForeground, double nSaturationMultForeground)
        {
            // struct MiniTileSetHeader { // mtshdr
            //  ushort offNext;
            //    ushort cTiles;
            //    ushort cxTile;
            //    ushort cyTile;
            // };

            ushort offNext = 0;
            if (fNext)
                offNext = (ushort)(8 + m_alsTileData.Count * cx * cx);
            bwtr.Write(Misc.SwapUShort(offNext));
            bwtr.Write(Misc.SwapUShort((ushort)m_alsTileData.Count));
            bwtr.Write(Misc.SwapUShort((ushort)cx));
            bwtr.Write(Misc.SwapUShort((ushort)cx));

            // If a background template exists, use it to distinguish foreground from background objects for better minimaps

            Size sizTile = tmpd.TileSize;
            ArrayList alsColors = new ArrayList();
            Template tmplBackground = tmpd.GetBackgroundTemplate();
            if (tmplBackground != null && nAreaBackgroundThreshold >= 0.0) {
                // Get despeckled hue map of background, calc mean and
                // std dev for filtering purposes

                Bitmap bmHueBackground = TemplateTools.MakeHueMap(tmplBackground.Bitmap);
                TemplateTools.DespeckleGrayscaleBitmap(bmHueBackground, 9, 50);
                double nMean = TemplateTools.CalcGrayscaleMean(bmHueBackground);
                double nStdDev = TemplateTools.CalcGrayscaleStandardDeviation(bmHueBackground, nMean);

                // Go through each tile, first make a mask that'll delineate foreground from background

                Bitmap bmTile = new Bitmap(sizTile.Width, sizTile.Height);
                foreach (TileData td in m_alsTileData) {
                    // Need to turn data back into a bitmap - doh!

                    for (int y = 0; y < sizTile.Height; y++) {
                        for (int x = 0; x < sizTile.Width; x++) {
                            Color clr = (Color)td.aclr[y * sizTile.Width + x];
                            bmTile.SetPixel(x, y, clr);
                        }
                    }

                    // Create mask which'll replace background with transparent color (255, 0, 255)

                    Bitmap bmMask = TemplateTools.MakeHueMap(bmTile);
                    TemplateTools.DespeckleGrayscaleBitmap(bmMask, 9, 50);
                    TemplateTools.SubtractGrayscaleDistribution(bmMask, nMean, nStdDev);

                    // Now scale tile down to desired size, using mask as input

                    Bitmap bmScaled = TemplateTools.ScaleTemplateBitmap(bmTile, bmMask, cx, cx, nAreaBackgroundThreshold, nLuminanceMultBackground, nSaturationMultBackground, nLuminanceMultForeground, nSaturationMultForeground);

                    // Grab the data

                    for (int y = 0; y < cx; y++) {
                        for (int x = 0; x < cx; x++) {
                            alsColors.Add(bmScaled.GetPixel(x, y));
                        }
                    }
                    bmScaled.Dispose();
                    bmMask.Dispose();
                }
            } else {
                // No background template; just scale

                Bitmap bmTile = new Bitmap(sizTile.Width, sizTile.Height);
                foreach (TileData td in m_alsTileData) {
                    // Need to turn data back into a bitmap - doh!

                    for (int y = 0; y < sizTile.Height; y++) {
                        for (int x = 0; x < sizTile.Width; x++) {
                            Color clr = (Color)td.aclr[y * sizTile.Width + x];
                            bmTile.SetPixel(x, y, clr);
                        }
                    }

                    // Now scale tile down to desired size, using mask as input

                    Bitmap bmScaled = TemplateTools.ScaleTemplateBitmap(bmTile, null, cx, cx, 1.0, 1.0, 1.0, 1.0, 1.0);

                    // Grab the data

                    for (int y = 0; y < cx; y++) {
                        for (int x = 0; x < cx; x++) {
                            alsColors.Add(bmScaled.GetPixel(x, y));
                        }
                    }
                    bmScaled.Dispose();
                }
            }

            // Palette match and write results

            foreach (Color clr in alsColors)
                bwtr.Write((byte)pal.FindClosestEntry(clr));
        }
示例#9
0
        unsafe int[][] GetScans(Bitmap bm)
        {
            // Special colors
            int[][] aaiclrScans = new int[m_cy][];

            // Lock down bits for speed
            Rectangle  rc     = new Rectangle(0, 0, m_cx, m_cy);
            BitmapData bmd    = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            byte *     pbBase = (byte *)bmd.Scan0.ToPointer();

            for (int y = 0; y < m_cy; y++)
            {
                int[] aiclrScan = new int[m_cx];
                for (int x = 0; x < m_cx; x++)
                {
                    // Get color
                    byte *pb  = pbBase + y * bmd.Stride + x * 3;
                    Color clr = Color.FromArgb(pb[2], pb[1], pb[0]);

                    if (clr == s_clrTransparent)
                    {
                        aiclrScan[x] = s_iclrTransparent;
                        continue;
                    }

                    if (clr == s_clrShadow)
                    {
                        aiclrScan[x] = s_iclrShadow;
                        continue;
                    }

                    if (clr == s_clrSideIndex0)
                    {
                        aiclrScan[x] = s_iclrSideFirst + 0;
                        continue;
                    }

                    if (clr == s_clrSideIndex1)
                    {
                        aiclrScan[x] = s_iclrSideFirst + 1;
                        continue;
                    }

                    if (clr == s_clrSideIndex2)
                    {
                        aiclrScan[x] = s_iclrSideFirst + 2;
                        continue;
                    }

                    if (clr == s_clrSideIndex3)
                    {
                        aiclrScan[x] = s_iclrSideFirst + 3;
                        continue;
                    }

                    if (clr == s_clrSideIndex4)
                    {
                        aiclrScan[x] = s_iclrSideFirst + 4;
                        continue;
                    }

                    aiclrScan[x] = m_pal.FindClosestEntry(clr);
                }
                aaiclrScans[y] = aiclrScan;
            }
            bm.UnlockBits(bmd);
            return(aaiclrScans);
        }
示例#10
0
        static unsafe int Main(string[] astrArgs)
        {
            // Command-line argument processing

            if (astrArgs.Length == 0) {
                PrintHelp();
                return 0;
            }

            for (int i = 0; i < astrArgs.Length; i++) {
                switch (astrArgs[i]) {
                case "-?":
                    PrintHelp();
                    return 0;

                case "-p":
                    gstrPalette = astrArgs[++i];
                    gpal = new Palette(gstrPalette);
                    break;

                case "-6":
                    gf6bitRGB = true;
                    break;

                default:
                    if (astrArgs[i][0] == '-') {
                        Console.WriteLine("Error: invalid flag '{0}'", astrArgs[i]);
                        return -1;
                    }

                    // Assume all 'unassociated' arguments are input filenames (potentially wildcarded)

                    string strDir = Path.GetDirectoryName(astrArgs[i]);
                    if (strDir == "")
                        strDir = ".";
                    string[] astrFileNames = Directory.GetFiles(strDir, Path.GetFileName(astrArgs[i]));

                    if (astrFileNames.Length == 0) {
                        gstrcFileNames.Add(astrArgs[i]);
                    } else {
                        foreach (string strFileName in astrFileNames) {
                            if (strFileName.ToLower().EndsWith(".ani")) {
                                string strT = Path.GetDirectoryName(strFileName) + @"\" + Path.GetFileNameWithoutExtension(strFileName) + @"\*.png";
                                string[] astrT = Directory.GetFiles(Path.GetDirectoryName(strT), Path.GetFileName(strT));
                                gstrcFileNames.AddRange(astrT);
                            } else {
                                gstrcFileNames.Add(strFileName);
                            }
                        }
                    }
                    break;
                }
            }

            if (gpal == null) {
                Console.WriteLine("A valid palette must be specified via the '-p' switch");
                return -1;
            }

            if (gstrcFileNames.Count == 0) {
                Console.WriteLine("Error: no files specified");
                return -1;
            }

            int nReturnValue = 0;
            Color clrShadow = Color.FromArgb(156, 212, 248);

            Console.Write("Verifying bitmap colors...");

            foreach (string strFileName in gstrcFileNames) {
                Hashtable htInvalidColors = new Hashtable();
                Bitmap bm = null;
                try {
                    bm = new Bitmap(strFileName);
                } catch {
                    Console.WriteLine("Error: {0} is not a recognized bitmap or palette file", strFileName);
                    continue;
                }

                Color clrTransparent = bm.GetPixel(0, 0);
                if (gf6bitRGB)
                    clrTransparent = Color.FromArgb(clrTransparent.R & 0xfc, clrTransparent.G & 0xfc, clrTransparent.B & 0xfc);

                // Lock down bits for speed

                Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
                BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte *pbBase = (byte *)bmd.Scan0.ToPointer();

                for (int y = 0; y < bm.Height; y++) {
                    for (int x = 0; x < bm.Width; x++) {
                        byte *pb = pbBase + y * bmd.Stride + x * 3;
                        Color clr;
                        if (gf6bitRGB)
                            clr = Color.FromArgb(pb[2] & 0xfc, pb[1] & 0xfc, pb[0] & 0xfc);
                        else
                            clr = Color.FromArgb(pb[2], pb[1], pb[0]);

                        int i = gpal.FindClosestEntry(clr);
                        if (gpal[i] != clr && clr != clrShadow && clr != clrTransparent && !htInvalidColors.ContainsKey(clr))
                                htInvalidColors.Add(clr, clr);
                    }
                }
                bm.UnlockBits(bmd);

                // Report any invalid colors

                if (htInvalidColors.Count != 0) {
                    if (nReturnValue == 0)
                        Console.WriteLine();
                    nReturnValue = -1;

                    int cclr = htInvalidColors.Count;

                    Color[] aclr = new Color[cclr];
                    htInvalidColors.Values.CopyTo(aclr, 0);
                    Console.Write("{0} contains {1} invalid color{2} (",
                            Path.GetFileName(strFileName), cclr, cclr == 1 ? "" : "s");
                    for (int i = 0; i < aclr.Length; i++) {
                        Color clr = aclr[i];
                        Console.Write("{0},{1},{2}", clr.R, clr.G, clr.B);
                        if (i != aclr.Length - 1)
                            Console.Write(", ");
                    }
                    Console.WriteLine(")");
                }
            }

            if (nReturnValue == 0)
                Console.WriteLine("done");
            return nReturnValue;
        }