예제 #1
0
        // todo not used, remove?
        //private static Rectangle letterRect(Bitmap source, int hStart, int hEnd)
        //{
        //    int startWhite = -1, endWhite = -1;
        //    for (int j = 0; j < source.Height; j++)
        //    {
        //        for (int i = hStart; i < hEnd; i++)
        //        {
        //            if (startWhite == -1 && source.GetPixel(i, j).R == 255)
        //            {
        //                startWhite = j;
        //            }

        //            if (endWhite == -1 && source.GetPixel(i, (source.Height - j) - 1).R == 255)
        //            {
        //                endWhite = (source.Height - j);
        //            }
        //            if (startWhite != -1 && endWhite != -1)
        //                return new Rectangle(hStart, startWhite, hEnd - hStart, endWhite - startWhite);
        //        }
        //    }


        //    return Rectangle.Empty;
        //}

        public float[] doOCR(out string OCRText, out string dinoName, out string species, out string ownerName, out string tribeName, out Sex sex, string useImageFilePath = "", bool changeForegroundWindow = true)
        {
            string finishedText = "";

            dinoName  = "";
            species   = "";
            ownerName = "";
            tribeName = "";
            sex       = Sex.Unknown;
            float[] finalValues = new float[1] {
                0
            };

            Bitmap screenshotbmp = null;
            Bitmap testbmp;

            ocrControl.debugPanel.Controls.Clear();
            ocrControl.ClearLists();

            if (System.IO.File.Exists(useImageFilePath))
            {
                screenshotbmp = (Bitmap)Bitmap.FromFile(useImageFilePath);
            }
            else
            {
                // grab screenshot from ark
                screenshotbmp = Win32Stuff.GetSreenshotOfProcess(screenCaptureApplicationName, waitBeforeScreenCapture, true);
            }
            if (screenshotbmp == null)
            {
                OCRText = "Error: no image for OCR. Is ARK running?";
                return(finalValues);
            }

            /*
             * // TODO resize image does not work well
             * if (screenshotbmp.Width != 1920 && screenshotbmp.Width != 1680)
             * {
             *  Bitmap resized = new Bitmap(1920, 1080);
             *  using (var graphics = Graphics.FromImage(resized))
             *  {
             *      graphics.CompositingMode = CompositingMode.SourceCopy;
             *      graphics.CompositingQuality = CompositingQuality.HighQuality;
             *      graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
             *      graphics.SmoothingMode = SmoothingMode.HighQuality;
             *      graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
             *
             *      using (var wrapMode = new ImageAttributes())
             *      {
             *          wrapMode.SetWrapMode(WrapMode.TileFlipXY);
             *          graphics.DrawImage(screenshotbmp, new Rectangle(0, 0, 1920, 1080), 0, 0, screenshotbmp.Width, screenshotbmp.Height, GraphicsUnit.Pixel, wrapMode);
             *      }
             *      screenshotbmp = resized;
             *  }
             * }
             */

            if (enableOutput)
            {
                AddBitmapToDebug(screenshotbmp);
                ocrControl.setScreenshot(screenshotbmp);
            }

            if (!setResolution(screenshotbmp))
            {
                OCRText = "Error while calibrating: probably game-resolution is not supported by this OCR-configuration.\nThe tested image has a resolution of " + screenshotbmp.Width.ToString() + "×" + screenshotbmp.Height.ToString() + " px.";
                return(finalValues);
            }
            finalValues = new float[ocrConfig.labelRectangles.Count];

            if (changeForegroundWindow)
            {
                Win32Stuff.SetForegroundWindow(Application.OpenForms[0].Handle);
            }


            bool wild = false; // todo: set to true and find out if the creature is wild in the first loop
            int  stI  = -1;

            for (int lbI = 0; lbI < ocrConfig.labelNames.Count; lbI++)
            {
                stI++;
                if (lbI == 8)
                {
                    stI = 8;
                }
                string statName = ocrConfig.labelNames[stI];

                Rectangle rec = ocrConfig.labelRectangles[lbI];

                // wild creatures don't have the xp-bar, all stats are moved one row up
                if (wild && stI < 9)
                {
                    rec.Offset(0, ocrConfig.labelRectangles[0].Top - ocrConfig.labelRectangles[1].Top);
                }

                testbmp = SubImage(screenshotbmp, rec.X, rec.Y, rec.Width, rec.Height);
                //AddBitmapToDebug(testbmp);

                string statOCR = "";

                if (statName == "NameSpecies")
                {
                    statOCR = readImage(testbmp, true, false);
                }
                else if (statName == "Level")
                {
                    statOCR = readImage(testbmp, true, true);
                }
                else if (statName == "Tribe" || statName == "Owner")
                {
                    statOCR = readImage(testbmp, true, false);
                }
                else
                {
                    statOCR = readImage(testbmp, true, true); // statvalues are only numbers
                }
                if (statOCR == "" &&
                    (statName == "Health" || statName == "Imprinting" || statName == "Tribe" || statName == "Owner"))
                {
                    if (wild && statName == "Health")
                    {
                        stI--;
                        wild = false;
                    }
                    continue; // these can be missing, it's fine
                }


                lastLetterPositions[statName] = new Point(rec.X + lastLetterPosition(removePixelsUnderThreshold(GetGreyScale(testbmp), whiteThreshold)), rec.Y);

                finishedText += (finishedText.Length == 0 ? "" : "\r\n") + statName + ":\t" + statOCR;

                // parse the OCR String

                Regex r;
                r       = new Regex(@"^[_\/\\]*(.*?)[_\/\\]*$"); // trim. often the background is misinterpreted as underscores or slash/backslash
                statOCR = r.Replace(statOCR, "$1");

                if (statName == "NameSpecies")
                {
                    r = new Regex(@".*?([♂♀])?[_.,-/\\]*(.+?)(?:[\(\[]([^\[\(\]\)]+)[\)\]]$|$)");
                }
                else if (statName == "Owner" || statName == "Tribe")
                {
                    r = new Regex(@"(.*)");
                }
                else if (statName == "Level")
                {
                    r = new Regex(@".*:(\d+)");
                }
                else
                {
                    r = new Regex(@"(?:\d+[\.,'][\d\/]%?[\/1])?(\d+[\.,']?\d?)(%)?"); // only the second numbers is interesting after the current weight is not shown anymore

                    //if (onlyNumbers)
                    //r = new Regex(@"((\d*[\.,']?\d?\d?)\/)?(\d*[\.,']?\d?\d?)");
                    //else
                    // r = new Regex(@"([a-zA-Z]*)[:;]((\d*[\.,']?\d?\d?)\/)?(\d*[\.,']?\d?\d?)");
                }

                MatchCollection mc = r.Matches(statOCR);

                if (mc.Count == 0)
                {
                    if (statName == "NameSpecies" || statName == "Owner" || statName == "Tribe")
                    {
                        continue;
                    }
                    else if (statName == "Torpor" && false)
                    {
                        // probably it's a wild creature
                        // todo
                    }
                    else
                    {
                        finishedText    += "error reading stat " + statName;
                        finalValues[stI] = 0;
                        continue;
                    }
                }

                if (statName == "NameSpecies" || statName == "Owner" || statName == "Tribe")
                {
                    if (statName == "NameSpecies" && mc[0].Groups.Count > 0)
                    {
                        if (mc[0].Groups[1].Value == "♀")
                        {
                            sex = Sex.Female;
                        }
                        else if (mc[0].Groups[1].Value == "♂")
                        {
                            sex = Sex.Male;
                        }
                        dinoName = mc[0].Groups[2].Value;
                        species  = mc[0].Groups[3].Value;
                        if (species.Length == 0)
                        {
                            species = dinoName;
                        }
                        // todo remove this removal, does the new ui show this?

                        /*
                         * // remove prefixes Baby, Juvenile and Adolescent
                         * r = new Regex("^(?:Ba[bh]y|Juven[il]le|Adolescent) *");
                         * dinoName = r.Replace(dinoName, "");
                         */
                        r        = new Regex("");
                        dinoName = r.Replace(dinoName, "");

                        // remove non-letter chars
                        r       = new Regex("[^a-zA-Z]");
                        species = r.Replace(species, "");
                        // replace capital I with lower l (common misrecognition)
                        r       = new Regex("(?<=[a-z])I(?=[a-z])");
                        species = r.Replace(species, "l");
                        // readd spaces before capital letters
                        r       = new Regex("(?<=[a-z])(?=[A-Z])");
                        species = r.Replace(species, " ");
                    }
                    else if (statName == "Owner" && mc[0].Groups.Count > 0)
                    {
                        ownerName = mc[0].Groups[0].Value;
                    }
                    else if (statName == "Tribe" && mc[0].Groups.Count > 0)
                    {
                        tribeName = mc[0].Groups[0].Value.Replace("Tobe", "Tribe").Replace("Tdbe", "Tribe").Replace("Tribeof", "Tribe of ");
                    }
                    continue;
                }

                if (mc[0].Groups.Count > 2 && mc[0].Groups[2].Value == "%" && statName == "Weight")
                {
                    // first stat with a '%' is damage, if oxygen is missing, shift all stats by one
                    finalValues[4] = finalValues[3]; // shift food to weight
                    finalValues[3] = finalValues[2]; // shift oxygen to food
                    finalValues[2] = 0;              // set oxygen (which wasn't there) to 0
                    stI++;
                }

                float v = 0;
                float.TryParse(mc[0].Groups[1].Value.Replace('\'', '.').Replace(',', '.').Replace('O', '0'), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.GetCultureInfo("en-US"), out v); // common substitutions: comma and apostrophe to dot,

                finishedText += "\t→ " + v.ToString();

                // TODO: test here that the read stat name corresponds to the stat supposed to be read
                finalValues[stI] = v;
            }

            OCRText = finishedText;

            return(finalValues);

            /*
             * Bitmap grab = Win32Stuff.GetSreenshotOfProcess(screenCaptureApplicationName);
             * AddBitmapToDebug(grab);
             *
             * //grab.Save("E:\\Temp\\Calibration8.png", ImageFormat.Png);
             * if (changeForegroundWindow)
             *  Win32Stuff.SetForegroundWindow(Application.OpenForms[0].Handle);
             */
        }