// OVERLOADED function to retrieve the results from the service process and load into 'Results' // Remember the character numbers returned refer to the Windows character set. private static bool GetResults(int JobNo, ref TOcrResultStructures.TOcrResults Results, ref int error) { int ResultsInf = 0; // number of bytes needed for results byte[] Bytes; int Offset; bool RetStatus = false; GCHandle BytesGC; IntPtr AddrOfItemBytes; Results.Hdr.NumItems = 0; if (TOCRGetJobResults(JobNo, ref ResultsInf, IntPtr.Zero) == TOCR_OK) { if (ResultsInf > 0) { Bytes = new Byte[ResultsInf - 1]; // pin the Bytes array so that TOCRGetJobResults can write to it BytesGC = GCHandle.Alloc(Bytes, GCHandleType.Pinned); if (TOCRGetJobResults(JobNo, ref ResultsInf, BytesGC.AddrOfPinnedObject()) == TOCR_OK) { Results.Hdr = ((TOcrResultStructures.TOcrResultsHeader)(Marshal.PtrToStructure(BytesGC.AddrOfPinnedObject(), typeof(TOcrResultStructures.TOcrResultsHeader)))); if (Results.Hdr.NumItems > 0) { Results.Item = new TOcrResultStructures.TOcrResultsItem[Results.Hdr.NumItems]; Offset = Marshal.SizeOf(typeof(TOcrResultStructures.TOcrResultsHeader)); for (int ItemNo = 0; ItemNo <= Results.Hdr.NumItems - 1; ItemNo++) { AddrOfItemBytes = Marshal.UnsafeAddrOfPinnedArrayElement(Bytes, Offset); Results.Item[ItemNo] = ((TOcrResultStructures.TOcrResultsItem)(Marshal.PtrToStructure(AddrOfItemBytes, typeof(TOcrResultStructures.TOcrResultsItem)))); Offset = Offset + Marshal.SizeOf(typeof(TOcrResultStructures.TOcrResultsItem)); } } RetStatus = true; // Double check results if (Results.Hdr.StructId == 0) { if (Results.Hdr.NumItems > 0) { if (Results.Item[0].StructId != 0) { error = -1;//ResultStructureError; Results.Hdr.NumItems = 0; RetStatus = false; } } } else { error = -2;//ResultHeaderStructureError; Results.Hdr.NumItems = 0; RetStatus = false; } } BytesGC.Free(); } } return(RetStatus); }
// OVERLOADED function to retrieve the results from the service process and load into 'Results' // Remember the character numbers returned refer to the Windows character set. private static bool GetResults(int JobNo, ref TOCRRESULTS Results) { int ResultsInf = 0; // number of bytes needed for results byte[] Bytes; int Offset; bool RetStatus = false; GCHandle BytesGC; System.IntPtr AddrOfItemBytes; Results.Hdr.NumItems = 0; if (TOCRGetJobResults(JobNo, ref ResultsInf, 0) == TOCR_OK) { if (ResultsInf > 0) { Bytes = new Byte[ResultsInf - 1]; // pin the Bytes array so that TOCRGetJobResults can write to it BytesGC = GCHandle.Alloc(Bytes, GCHandleType.Pinned); if (TOCRdeclares.TOCRGetJobResults(JobNo, ref ResultsInf, ref Bytes[0]) == TOCR_OK) { Results.Hdr = ((TOCRRESULTSHEADER)(Marshal.PtrToStructure(BytesGC.AddrOfPinnedObject(), typeof(TOCRRESULTSHEADER)))); if (Results.Hdr.NumItems > 0) { Results.Item = new TOCRRESULTSITEM[Results.Hdr.NumItems]; Offset = Marshal.SizeOf(typeof(TOCRRESULTSHEADER)); for (int ItemNo = 0; ItemNo <= Results.Hdr.NumItems - 1; ItemNo++) { AddrOfItemBytes = Marshal.UnsafeAddrOfPinnedArrayElement(Bytes, Offset); Results.Item[ItemNo] = ((TOCRRESULTSITEM)(Marshal.PtrToStructure(AddrOfItemBytes, typeof(TOCRRESULTSITEM)))); Offset = Offset + Marshal.SizeOf(typeof(TOCRRESULTSITEM)); } } RetStatus = true; // Double check results if (Results.Hdr.StructId == 0) { if (Results.Hdr.NumItems > 0) { if (Results.Item[0].StructId != 0) { MessageBox.Show("Wrong results item structure Id " + Results.Item[0].StructId.ToString(), "GetResults", MessageBoxButtons.OK, MessageBoxIcon.Stop); Results.Hdr.NumItems = 0; RetStatus = false; } } } else { MessageBox.Show("Wrong results header structure Id " + Results.Item[0].StructId.ToString(), "GetResults", MessageBoxButtons.OK, MessageBoxIcon.Stop); Results.Hdr.NumItems = 0; RetStatus = false; } } BytesGC.Free(); } } return(RetStatus); }
// Convert a bitmap to a memory mapped file. // It does this by constructing a GDI bitmap in a byte array and copying this to a memory mapped file. private IntPtr ConvertBitmapToMMF(Bitmap BMPIn, bool DiscardBitmap, bool ConvertTo1Bit) { Bitmap BMP; BITMAPINFOHEADER BIH; BitmapData BMPData; int ImageSize; byte[] Bytes; GCHandle BytesGC; int MMFsize; int PalEntries; RGBQUAD rgb; int Offset; IntPtr MMFhandle = IntPtr.Zero; IntPtr MMFview = IntPtr.Zero; IntPtr RetPtr = IntPtr.Zero; if (DiscardBitmap) // can destroy input bitmap { if (ConvertTo1Bit && BMPIn.PixelFormat != PixelFormat.Format1bppIndexed) { BMP = ConvertTo1bpp(BMPIn); BMPIn.Dispose(); BMPIn = null; } else { BMP = BMPIn; } } else // must keep input bitmap unchanged { if (ConvertTo1Bit && BMPIn.PixelFormat != PixelFormat.Format1bppIndexed) { BMP = ConvertTo1bpp(BMPIn); } else { BMP = BMPIn.Clone(new Rectangle(new Point(), BMPIn.Size), BMPIn.PixelFormat); } } // Flip the bitmap (GDI+ bitmap scan lines are top down, GDI are bottom up) BMP.RotateFlip(RotateFlipType.RotateNoneFlipY); BMPData = BMP.LockBits(new Rectangle(new Point(), BMP.Size), ImageLockMode.ReadOnly, BMP.PixelFormat); ImageSize = BMPData.Stride * BMP.Height; PalEntries = BMP.Palette.Entries.Length; BIH.biWidth = BMP.Width; BIH.biHeight = BMP.Height; BIH.biPlanes = 1; BIH.biClrImportant = 0; BIH.biCompression = BI_RGB; BIH.biSizeImage = (uint)ImageSize; BIH.biXPelsPerMeter = System.Convert.ToInt32(BMP.HorizontalResolution * 100 / 2.54); BIH.biYPelsPerMeter = System.Convert.ToInt32(BMP.VerticalResolution * 100 / 2.54); BIH.biBitCount = 0; // to avoid "Use of unassigned local variable 'BIH'" BIH.biSize = 0; // to avoid "Use of unassigned local variable 'BIH'" BIH.biClrImportant = 0; // to avoid "Use of unassigned local variable 'BIH'" // Most of these formats are untested and the alpha channel is ignored switch (BMP.PixelFormat) { case PixelFormat.Format1bppIndexed: BIH.biBitCount = 1; break; case PixelFormat.Format4bppIndexed: BIH.biBitCount = 4; break; case PixelFormat.Format8bppIndexed: BIH.biBitCount = 8; break; case PixelFormat.Format16bppArgb1555: case PixelFormat.Format16bppGrayScale: case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppRgb565: BIH.biBitCount = 16; PalEntries = 0; break; case PixelFormat.Format24bppRgb: BIH.biBitCount = 24; PalEntries = 0; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: case PixelFormat.Format32bppRgb: BIH.biBitCount = 32; PalEntries = 0; break; } BIH.biClrUsed = (uint)PalEntries; BIH.biSize = (uint)Marshal.SizeOf(BIH); MMFsize = Marshal.SizeOf(BIH) + PalEntries * Marshal.SizeOf(typeof(RGBQUAD)) + ImageSize; Bytes = new byte[MMFsize]; BytesGC = GCHandle.Alloc(Bytes, GCHandleType.Pinned); Marshal.StructureToPtr(BIH, BytesGC.AddrOfPinnedObject(), true); Offset = Marshal.SizeOf(BIH); rgb.rgbReserved = 0; for (int PalEntry = 0; PalEntry <= PalEntries - 1; PalEntry++) { rgb.rgbRed = BMP.Palette.Entries[PalEntry].R; rgb.rgbGreen = BMP.Palette.Entries[PalEntry].G; rgb.rgbBlue = BMP.Palette.Entries[PalEntry].B; Marshal.StructureToPtr(rgb, Marshal.UnsafeAddrOfPinnedArrayElement(Bytes, Offset), false); Offset = Offset + Marshal.SizeOf(rgb); } BytesGC.Free(); Marshal.Copy(BMPData.Scan0, Bytes, Offset, ImageSize); BMP.UnlockBits(BMPData); BMPData = null; BMP.Dispose(); BMP = null; MMFhandle = CreateFileMappingMy(0xFFFFFFFF, 0, PAGE_READWRITE, 0, (uint)MMFsize, 0); if (!(MMFhandle.Equals(IntPtr.Zero))) { MMFview = MapViewOfFileMy(MMFhandle, FILE_MAP_WRITE, 0, 0, 0); if (MMFview.Equals(IntPtr.Zero)) { CloseHandle(MMFhandle); } else { Marshal.Copy(Bytes, 0, MMFview, MMFsize); UnmapViewOfFileMy(MMFview); RetPtr = MMFhandle; } } Bytes = null; if (RetPtr.Equals(IntPtr.Zero)) { //MessageBox.Show("Failed to convert bitmap", "ConvertBitmapToMMF", MessageBoxButtons.OK, MessageBoxIcon.Stop); } return(RetPtr); }
// OVERLOADED function to retrieve the results from the service process and load into 'ResultsEx' // Remember the character numbers returned refer to the Windows character set. private bool GetResults(int JobNo, ref TOCRRESULTSEX ResultsEx) { int ResultsInf = 0; byte[] Bytes; int Offset; bool RetStatus = false; TOCRRESULTSITEMEXHDR ItemHdr; GCHandle BytesGC; System.IntPtr AddrOfItemBytes; ResultsEx.Hdr.NumItems = 0; if (TOCRGetJobResultsEx(JobNo, TOCRGETRESULTS_EXTENDED, ref ResultsInf, IntPtr.Zero) == TOCR_OK) { if (ResultsInf > 0) { Bytes = new Byte[ResultsInf - 1]; // pin the Bytes array so that TOCRGetJobResultsEx can write to it BytesGC = GCHandle.Alloc(Bytes, GCHandleType.Pinned); if (TOCRGetJobResultsEx(JobNo, TOCRGETRESULTS_EXTENDED, ref ResultsInf, BytesGC.AddrOfPinnedObject()) == TOCR_OK) { ResultsEx.Hdr = ((TOCRRESULTSHEADER)(Marshal.PtrToStructure(BytesGC.AddrOfPinnedObject(), typeof(TOCRRESULTSHEADER)))); if (ResultsEx.Hdr.NumItems > 0) { ResultsEx.Item = new TOCRRESULTSITEMEX[ResultsEx.Hdr.NumItems]; Offset = Marshal.SizeOf(typeof(TOCRRESULTSHEADER)); for (int ItemNo = 0; ItemNo <= ResultsEx.Hdr.NumItems - 1; ItemNo++) { ResultsEx.Item[ItemNo].Alt = new TOCRRESULTSITEMEXALT[5]; // Cannot Marshal TOCRRESULTSITEMEX so use copy of structure header // This unfortunately means a double copy of the data AddrOfItemBytes = Marshal.UnsafeAddrOfPinnedArrayElement(Bytes, Offset); ItemHdr = ((TOCRRESULTSITEMEXHDR)(Marshal.PtrToStructure(AddrOfItemBytes, typeof(TOCRRESULTSITEMEXHDR)))); ResultsEx.Item[ItemNo].StructId = ItemHdr.StructId; ResultsEx.Item[ItemNo].OCRCha = ItemHdr.OCRCha; ResultsEx.Item[ItemNo].Confidence = ItemHdr.Confidence; ResultsEx.Item[ItemNo].XPos = ItemHdr.XPos; ResultsEx.Item[ItemNo].YPos = ItemHdr.YPos; ResultsEx.Item[ItemNo].XDim = ItemHdr.XDim; ResultsEx.Item[ItemNo].YDim = ItemHdr.YDim; Offset = Offset + Marshal.SizeOf(typeof(TOCRRESULTSITEMEXHDR)); for (int AltNo = 0; AltNo < 5; AltNo++) { AddrOfItemBytes = Marshal.UnsafeAddrOfPinnedArrayElement(Bytes, Offset); ResultsEx.Item[ItemNo].Alt[AltNo] = ((TOCRRESULTSITEMEXALT)(Marshal.PtrToStructure(AddrOfItemBytes, typeof(TOCRRESULTSITEMEXALT)))); Offset = Offset + Marshal.SizeOf(typeof(TOCRRESULTSITEMEXALT)); } } } RetStatus = true; // Double check results if (ResultsEx.Hdr.StructId == 0) { if (ResultsEx.Hdr.NumItems > 0) { if (ResultsEx.Item[0].StructId != 0) { //MessageBox.Show("Wrong results item structure Id " + ResultsEx.Item[0].StructId.ToString(), "GetResultsEx", MessageBoxButtons.OK, MessageBoxIcon.Stop); ResultsEx.Hdr.NumItems = 0; RetStatus = false; } } } else { //MessageBox.Show("Wrong results header structure Id " + ResultsEx.Item[0].StructId.ToString(), "GetResults", MessageBoxButtons.OK, MessageBoxIcon.Stop); ResultsEx.Hdr.NumItems = 0; RetStatus = false; } } BytesGC.Free(); } } return(RetStatus); }