查找图像内容并在其周围绘制矩形

2024-02-08

About

我在用着WinForms。在我的表格中,我有一个picturebox. The picturebox尺寸模式设置为zoom。我用picturebox查看 TIF 图像。 TIF 图像是灰度图像(仅黑白).

我的应用程序做什么

我的应用程序找到文档中的第一个黑色像素和最后一个黑色像素,并在其周围绘制一个红色矩形。希望它能在图像内容周围绘制矩形。

问题

有时,TIF 文档的图像内容周围有斑点/圆点。这让我的申请失败了。它不知道图像内容从哪里开始和结束。如果文档有斑点/圆点,如何找到 TIF 文档的内容并在其周围绘制矩形?

关于文件

  • 仅黑白(1 位深度)
  • TIF文件
  • 文档总是包含字母和数字
  • 字母和数字总是比点/点大
  • 即使在内容中,图像中也可能存在多个斑点
  • 背景始终是白色的
  • 内容始终是黑色的
  • 斑点也是黑色的

下载测试图片链接:

• 文件释放器: http://www.filedropper.com/test-tifs http://www.filedropper.com/test-tifs

• 快速共享: https://ufile.io/2qiir https://ufile.io/2qiir


我发现了什么

经过研究,我发现 AForge.Imaging 库有许多图像过滤器,可能会帮助我实现我的目标。我正在考虑使用中值滤波器去除斑点/点或使用其他滤波器来实现所需的结果。

我尝试过的

我尝试应用 AForge 库中的中值滤波器来去除这些斑点,但这只去除了一些斑点。我不得不多次重复回复过滤器,以消除大部分位置来查找内容,但仍然很难找到内容。这个方法对我来说效果不太好。

AForge 过滤器链接: http://www.aforgenet.com/framework/docs/html/cdf93487-0659-e371-fed9-3b216efb6954.htm http://www.aforgenet.com/framework/docs/html/cdf93487-0659-e371-fed9-3b216efb6954.htm


Code

    private void btn_Draw_Click(object sender, EventArgs e)
    {
        // Wrap the creation of the OpenFileDialog instance in a using statement,
        // rather than manually calling the Dispose method to ensure proper disposal
        using (OpenFileDialog dlg = new OpenFileDialog())
        {
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                pictureBox1.Image = new Bitmap(dlg.FileName);

                int xMax = pictureBox1.Image.Width;
                int yMax = pictureBox1.Image.Height;

                startX = Int32.MaxValue;
                startY = Int32.MaxValue;
                endX = Int32.MinValue;
                endY = Int32.MinValue;


                using (Bitmap bmp = new Bitmap(pictureBox1.Image))
                {
                    for (var y = 0;  y < yMax; y+=3)
                    {
                        for (var x = 0; x < xMax; x+=3)
                        {
                            Color col = bmp.GetPixel(x, y);
                            if(col.ToArgb() == Color.Black.ToArgb())
                            {
                                // Finds first black pixel
                                if (x < startX)
                                    startX = x;
                                if(y < startY)
                                    startY = y;

                                // Finds last black pixel
                                if (x > endX)
                                    endX = x;
                                if (y > endY)
                                    endY = y;
                            }
                        }
                    }


                    int picWidth = pictureBox1.Size.Width;
                    int picHeight = pictureBox1.Size.Height;


                    float imageRatio = xMax / (float)yMax; // image W:H ratio
                    float containerRatio = picWidth / (float)picHeight; // container W:H ratio

                    if (imageRatio >= containerRatio)
                    {
                        // horizontal image
                        float scaleFactor = picWidth / (float)xMax;
                        float scaledHeight = yMax * scaleFactor;
                        // calculate gap between top of container and top of image
                        float filler = Math.Abs(picHeight - scaledHeight) / 2;
                        //float filler = 0;

                        startX = (int)(startX * scaleFactor);
                        endX = (int)(endX * scaleFactor);
                        startY = (int)((startY) * scaleFactor + filler);
                        endY = (int)((endY) * scaleFactor + filler);
                    }
                    else
                    {
                        // vertical image
                        float scaleFactor = picHeight / (float)yMax;
                        float scaledWidth = xMax * scaleFactor;
                        float filler = Math.Abs(picWidth - scaledWidth) / 2;
                        startX = (int)((startX) * scaleFactor + filler);
                        endX = (int)((endX) * scaleFactor + filler);
                        startY = (int)(startY * scaleFactor);
                        endY = (int)(endY * scaleFactor);
                    }

                    //var scaleX = picWidth / (float)xMax;
                    //var scaleY = picHeight / (float)yMax;

                    //startX = (int)Math.Round(startX * scaleX);
                    //startY = (int)Math.Round(startY * scaleY);
                    //endX = (int)Math.Round(endX * scaleX);
                    //endY = (int)Math.Round(endY * scaleY);

                }
            }
        }
    }

    private bool _once = true;
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        if (_once)
        {
            //Rectangle ee = new Rectangle(35, 183, 405, 157);
            Rectangle ee = new Rectangle(startX, startY, endX - startX, endY - startY);
            System.Diagnostics.Debug.WriteLine(startX + ", " + startY + ", " + (endX - startX) + ", " + (endY - startY));
            using (Pen pen = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawRectangle(pen, ee);
            }
            //_once = false;
        }
    }

内容周围没有任何斑点的 Tif 文档

Tif document that HAS spots and dots around content enter image description here

示例图 1:


示例图 2


enter image description here:

示例图 3



以下实验似乎可以满足您的所有要求。

我在 Form 1 上放置了以下控件

一个 MenuStrip:Docking=Top,有 2 个菜单项 - 一个用于打开文件,第二个用于运行算法

进度条:Docking=Top,观察加载和算法的表现

Docking=Fill 和 AutoScroll=true 的面板

一张图片放入面板,Point(0,0),其余默认。尺寸模式=正常。

Update

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Opens an image file.
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.image = Image.FromFile(dlg.FileName) as Bitmap;
                this.pictureBox1.Image = image;
                this.pictureBox1.Invalidate();
            }
        }

        Bitmap image;

        // finds top, left, right and bottom bounds of the content in TIFF file.
        // 
        private void findBoundsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int contentSize = 70;

            this.left = 0;
            this.top = 0;
            this.right = this.pictureBox1.Width - 1;
            this.bottom = this.pictureBox1.Height - 1;

            int h = image.Height;
            int w = image.Width;
            this.progressBar1.Value = 0;
            this.progressBar1.Maximum = 4;

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {

                    if (this.image.GetPixel(x, y).ToArgb() == Black)
                    {
                        int size = this.image.GetBlackRegionSize(x, y);
                        if (this.image.GetBlackRegionSize(x, y) > contentSize)
                        {
                            this.top = y;
                            goto label10;
                        }
                    }

                }
            }

        label10:
            this.progressBar1.Increment(1);
            for (int y = h - 1; y >= 0; y--)
            {
                for (int x = 0; x < w; x++)
                {

                    if (this.image.GetPixel(x, y).ToArgb() == Black)
                    {
                        if (this.image.GetBlackRegionSize(x, y) > contentSize)
                        {
                            this.bottom = y;
                            goto label11;
                        }
                    }
                }
            }

        label11:
            this.progressBar1.Increment(1);
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {

                    if (this.image.GetPixel(x, y).ToArgb() == Black)
                    {
                        if (this.image.GetBlackRegionSize(x, y) > contentSize)
                        {
                            this.left = x;
                            goto label12;
                        }
                    }
                }
            }

        label12:
            this.progressBar1.Increment(1);
            for (int x = w - 1; x >= 0; x--)
            {
                for (int y = 0; y < h; y++)
                {

                    if (this.image.GetPixel(x, y).ToArgb() == Black)
                    {
                        if (this.image.GetBlackRegionSize(x, y) > contentSize)
                        {
                            this.right = x;
                            goto label13;
                        }
                    }
                }
            }

        label13:
            this.progressBar1.Increment(1);

            this.pictureBox1.Invalidate();
        }

        internal static readonly int Black = Color.Black.ToArgb();
        internal static readonly int White = Color.White.ToArgb();

        int top;
        int bottom;
        int left;
        int right;

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (pictureBox1.Image == null)
            {
                return;
            }

            int xMax = pictureBox1.Image.Width;
            int yMax = pictureBox1.Image.Height;

            int startX = this.left;
            int startY = this.top;
            int endX = this.right;
            int endY = this.bottom;


            int picWidth = pictureBox1.Size.Width;
            int picHeight = pictureBox1.Size.Height;


            float imageRatio = xMax / (float)yMax; // image W:H ratio
            float containerRatio = picWidth / (float)picHeight; // container W:H ratio

            if (imageRatio >= containerRatio)
            {
                // horizontal image
                float scaleFactor = picWidth / (float)xMax;
                float scaledHeight = yMax * scaleFactor;
                // calculate gap between top of container and top of image
                float filler = Math.Abs(picHeight - scaledHeight) / 2;
                //float filler = 0;

                startX = (int)(startX * scaleFactor);
                endX = (int)(endX * scaleFactor);
                startY = (int)((startY) * scaleFactor + filler);
                endY = (int)((endY) * scaleFactor + filler);
            }
            else
            {
                // vertical image
                float scaleFactor = picHeight / (float)yMax;
                float scaledWidth = xMax * scaleFactor;
                float filler = Math.Abs(picWidth - scaledWidth) / 2;
                startX = (int)((startX) * scaleFactor + filler);
                endX = (int)((endX) * scaleFactor + filler);
                startY = (int)(startY * scaleFactor);
                endY = (int)(endY * scaleFactor);
            }

            //if (_once)
            //Rectangle ee = new Rectangle(35, 183, 405, 157);
            Rectangle ee = new Rectangle(startX, startY, endX - startX, endY - startY);
            System.Diagnostics.Debug.WriteLine(startX + ", " + startY + ", " + (endX - startX) + ", " + (endY - startY));
            using (Pen pen = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawRectangle(pen, ee);
            }
            //_once = false;
        }
    }

    static class BitmapHelper
    {
        internal static int GetBlackRegionSize(this Bitmap image, int x, int y)
        {
            int size = 0;
            GetRegionSize(image, new List<Point>(), x, y, 0, ref size);
            return size;
        }

        // this constant prevents StackOverFlow exception.
        // also it has effect on performance.
        // It's value must be greater than the value of contentSize defined in findBoundsToolStripMenuItem_Click(object sender, EventArgs e) method.
        const int MAXLEVEL = 100;

        static void GetRegionSize(this Bitmap image, List<Point> list, int x, int y, int level, ref int size)
        {
            if (x >= image.Width || x < 0 || y >= image.Height || y < 0 || list.Contains(x, y) || image.GetPixel(x, y).ToArgb() != Form1.Black || level > MAXLEVEL)
            {
                return;
            }

            if (size < level)
            {
                size = level;
            }

            list.Add(new Point(x, y));

            image.GetRegionSize(list, x, y - 1, level + 1, ref size);
            image.GetRegionSize(list, x, y + 1, level + 1, ref size);
            image.GetRegionSize(list, x - 1, y, level + 1, ref size);
            image.GetRegionSize(list, x + 1, y, level + 1, ref size);
        }

        static bool Contains(this List<Point> list, int x, int y)
        {
            foreach (Point point in list)
            {
                if (point.X == x && point.Y == y)
                {
                    return true;
                }
            }
            return false;
        }
    }

}

“这个.pictureBox1.Size = image.Size;”已被删除。 Paint 事件处理程序的代码已更改。 PictureBox尺寸模式现在可以设置为缩放。

Update 2

我尝试简化代码并提高性能。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
        }

        // Opens an image file
        // and runs "FindBounds()" method
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.image = Image.FromFile(dlg.FileName) as Bitmap;
                FindBounds();
                this.pictureBox1.Image = image;
                this.pictureBox1.Invalidate();
            }
        }

        Bitmap image;

        // Possible maximum side of a spot or a dot in the image
        int maxSpotOrDotSide = 7;

        // Finds top, left, right and bottom bounds of the content in TIFF file.
        private void FindBounds()
        {
            // Possible maximum area of a spot or a dot in the image
            int maxSpotOrDotArea = maxSpotOrDotSide * maxSpotOrDotSide;

            this.left = 0;
            this.top = 0;
            this.right = this.pictureBox1.Width - 1;
            this.bottom = this.pictureBox1.Height - 1;

            int h = image.Height;
            int w = image.Width;
            int num = w * h;

            // Incrementers. I tested with greater values
            // like "x = 2", "x = 5" and it increased performance.
            // But we must be carefull as this may cause skipping content.
            int dx = 1; // Incrementer for "x"
            int dy = 1; // Incrementer for "y"

            // Initialization of "progressBar1"
            this.progressBar1.Value = 0;
            this.progressBar1.Maximum = num;

            // Content of the image
            BlackContent imageContent = null;

            // Here we will scan pixels of the image
            // starting from top left corner and 
            // finishing at bottom right
            for (int y = 0; y < h; y += dx)
            {
                for (int x = 0; x < w; x += dy)
                {
                    int val = y * w + x;
                    this.progressBar1.Value = val > num ? num : val;
                    // This block skips scanning imageContent
                    // thus should increase performance.
                    if (imageContent != null && imageContent.Contains(x, y))
                    {
                        x = imageContent.Right;
                        continue;
                    }

                    // Interesting things begin to happen
                    // after we detect the first Black pixel
                    if (this.image.GetPixel(x, y).ToArgb() == Black)
                    {
                        BlackContent content = new BlackContent(x, y);
                        // Start Flood-Fill algorithm
                        content.FloodFill(this.image);
                        if (content.Area > maxSpotOrDotArea)
                        {
                            if (imageContent == null)
                            {
                                imageContent = content;
                            }
                            imageContent.Include(content.Right, content.Bottom);
                            imageContent.Include(content.Left, content.Top);
                        }
                        else
                        {
                            // Here it's better we increase values of the incrementers.
                            // Depending on size of spots/dots.
                            // It should increase performance.
                            if (dx < content.Width) dx = content.Width;
                            if (dy < content.Height) dy = content.Height;
                        }
                    }

                }
            }

            // Everything is done.
            this.progressBar1.Value = this.progressBar1.Maximum;

            // If image content has been detected 
            // then we save the information
            if (imageContent != null)
            {
                this.left = imageContent.Left;
                this.top = imageContent.Top;
                this.right = imageContent.Right;
                this.bottom = imageContent.Bottom;
            }

            this.pictureBox1.Invalidate();
        }

        internal static readonly int Black = Color.Black.ToArgb();
        internal static readonly int White = Color.White.ToArgb();

        int top;
        int bottom;
        int left;
        int right;

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (pictureBox1.Image == null)
            {
                return;
            }

            int xMax = pictureBox1.Image.Width;
            int yMax = pictureBox1.Image.Height;

            int startX = this.left;
            int startY = this.top;
            int endX = this.right;
            int endY = this.bottom;


            int picWidth = pictureBox1.Size.Width;
            int picHeight = pictureBox1.Size.Height;


            float imageRatio = xMax / (float)yMax; // image W:H ratio
            float containerRatio = picWidth / (float)picHeight; // container W:H ratio

            if (imageRatio >= containerRatio)
            {
                // horizontal image
                float scaleFactor = picWidth / (float)xMax;
                float scaledHeight = yMax * scaleFactor;
                // calculate gap between top of container and top of image
                float filler = Math.Abs(picHeight - scaledHeight) / 2;
                //float filler = 0;

                startX = (int)(startX * scaleFactor);
                endX = (int)(endX * scaleFactor);
                startY = (int)((startY) * scaleFactor + filler);
                endY = (int)((endY) * scaleFactor + filler);
            }
            else
            {
                // vertical image
                float scaleFactor = picHeight / (float)yMax;
                float scaledWidth = xMax * scaleFactor;
                float filler = Math.Abs(picWidth - scaledWidth) / 2;
                startX = (int)((startX) * scaleFactor + filler);
                endX = (int)((endX) * scaleFactor + filler);
                startY = (int)(startY * scaleFactor);
                endY = (int)(endY * scaleFactor);
            }

            //if (_once)
            //Rectangle ee = new Rectangle(35, 183, 405, 157);
            Rectangle ee = new Rectangle(startX, startY, endX - startX, endY - startY);
            System.Diagnostics.Debug.WriteLine(startX + ", " + startY + ", " + (endX - startX) + ", " + (endY - startY));
            using (Pen pen = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawRectangle(pen, ee);
            }
            //_once = false;
        }
    }

    // This class is similar to System.Drawing.Region class
    // except that its only rectangular. 
    // Because all we need is to draw a rectagnle
    // around the image this property must 
    // make it faster, at least I hope so.

    class BlackContent
    {
        internal void FloodFill(Bitmap image)
        {
            FloodFillPrivate(image, this.left + 1, this.top, 0);
        }

        // Legendary Flood-Fill algorithm.
        // Quite often it ends up with StackOverFlow exception.
        // But this class and its rectangularity property
        // must prevent this disaster.
        // In my experiments I didn't encounter incidents.
        void FloodFillPrivate(Bitmap image, int x, int y, int level)
        {
            if (x >= image.Width || x < 0 || y >= image.Height || y < 0 || this.Contains(x, y) || image.GetPixel(x, y).ToArgb() != Form1.Black)
            {
                return;
            }

            this.Include(x, y);

            FloodFillPrivate(image, x, y - 1, level + 1);
            FloodFillPrivate(image, x, y + 1, level + 1);
            FloodFillPrivate(image, x - 1, y, level + 1);
            FloodFillPrivate(image, x + 1, y, level + 1);
        }

        internal BlackContent(int x, int y)
        {
            this.left = x;
            this.right = x;
            this.top = y;
            this.bottom = y;
        }

        internal void Include(int x, int y)
        {
            if (x < this.left)
            {
                this.left = x;
            }
            if (this.right < x)
            {
                this.right = x;
            }
            if (this.bottom < y)
            {
                this.bottom = y;
            }
            if (y < this.top)
            {
                this.top = y;
            }
        }

        internal bool Contains(int x, int y)
        {
            return !(x < this.left || x > this.right || y < this.top || y > this.bottom);
        }

        int left;
        internal int Left { get { return this.left; } }
        int top;
        internal int Top { get { return this.top; } }
        int right;
        internal int Right { get { return this.right; } }
        int bottom;
        internal int Bottom { get { return this.bottom; } }

        internal int Area
        {
            get
            {
                return Width * Height;
            }
        }

        internal int Width
        {
            get
            {
                return (this.right - this.left + 1);
            }
        }

        internal int Height
        {
            get
            {
                return (this.bottom - this.top + 1);
            }
        }
    }

}

我用ProgressBar观看了表演。这个速度相当快。 我还必须提到你的图像太大了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找图像内容并在其周围绘制矩形 的相关文章

  • 基于多线程的 RabbitMQ 消费者

    我们有一个 Windows 服务 它监听单个 RabbitMQ 队列并处理消息 我们希望扩展相同的 Windows 服务 以便它可以监听 RabbitMQ 的多个队列并处理消息 不确定使用多线程是否可以实现这一点 因为每个线程都必须侦听 阻
  • ptrace和waitpid有什么关系?

    我正在练习使用ptrace但我不太了解它和之间的关系waitpid 这是我的测试程序 int main int argc char argv pid t pid 22092 if ptrace PTRACE ATTACH pid NULL
  • 为基于架构的 XML 文件创建 WPF 编辑器

    这是场景 我们的服务器产品之一使用大型 XML 配置文件 该文件的布局相当好 并且针对 XSD 文件进行了验证 现在是时候构建一个配置 GUI 来维护这个文件了 我想深入研究 WPF 来完成它 我可以为每个配置部分布置一个单独的表单 每次向
  • C# 中输入按键

    我尝试了这段代码 private void textBox1 KeyPress object sender KeyPressEventArgs e if Convert ToInt32 e KeyChar 13 MessageBox Sho
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 如何在控制器中使用多个 DBContext

    如何在控制器中使用多个 DBContext 我尝试以不同的方式重载构造函数 一些控制器 public C1 DBContext1 a DBContext2 b DBContext3 c public C1 DBContext1 a publ
  • Xcode 新手无法用 C++ 打开文件?

    我一直在我参加的课程中使用 Windows 但我正在尝试运行基本代码来弄清楚如何从 Xcode 上的文件打开 关闭 输入 输出 而我通常在 Visual Studio 上使用的代码不是不知道为什么 谢谢 include
  • 如何检查给定调用站点的重载决策集

    如何检查重载解析集 我在多个调用站点中使用了 4 个相互竞争的函数 在一个调用站点中 我期望调用一个函数 但编译器会选择另一个函数 我不知道为什么 这不是微不足道的 为了了解发生了什么 我正在使用enable if disable if打开
  • 如何使用 Selenium Webdriver .NET 绑定设置 Chrome 首选项?

    这是我正在使用的 用户代理可以成功设置 而下载首选项则不能 Windows 7 Chrome 26 Selenium dotnet 2 31 2 chromedriver win 26 0 1383 0 ChromeOptions chro
  • 代码块 - 使用大地址感知标志进行编译

    如何使用以下命令在 64 位系统上编译 32 位应用程序LARGE ADRESS AWARE使用代码块标记 我需要使用超过 2GB 的内存 应该是添加的情况 Wl large address aware到链接标志 我不使用 CodeBloc
  • 使用 ClosedXML 附加到 excel 文件

    我需要将新数据附加到使用 ClosedXML 创建的现有 Excel 文件中 如何使用 ClosedXML 附加到 Excel 文件 如何获取最后一条记录的行号并将其附加到该行号上 或者还有其他内容 Thanks 打开现有工作簿 然后使用L
  • 为什么 std::atomic 比 volatile bool 慢很多?

    多年来我一直使用 volatile bool 来控制线程执行 并且效果很好 in my class declaration volatile bool stop In the thread function while stop do th
  • C++ 更改屏幕方向问题 -- DEVMODE dmDisplayOrientation DMDO_90 undefined

    我似乎无法编译一些 C 代码 我正在翻转显示器的方向 但 VS2008 告诉我 DMDO 90 和 DMDO 270 无法识别 error C2065 DMDO 90 undeclared identifier error C2065 DM
  • C# 从今天起 30 天

    我需要我的应用程序从今天起 30 天后过期 我会将当前日期存储在应用程序配置中 如何检查应用程序是否已过期 我不介意用户是否将时钟调回来并且应用程序可以正常工作 用户太愚蠢而不会这样做 if appmode Trial string dat
  • 为什么将未使用的返回值转换为 void?

    int fn void whatever void fn 是否有任何理由将未使用的返回值强制转换为 void 或者我认为这完全是浪费时间 David s answer https stackoverflow com questions 68
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor
  • OpenSSL:无需 SSL_read() / SSL_write() 即可执行加密/解密

    我已经用 C 语言编写了一个基于事件的网络库 现在我想通过 OpenSSL 添加 SSL TLS 支持 而不是使用SSL read and SSL write 我宁愿让 OpenSSL 只执行传出 传入数据的加密 解密 让我自己传输 接收数
  • OpenCV 仅围绕大轮廓绘制矩形?

    第一次发帖 希望我以正确的方式放置代码 我正在尝试检测和计算视频中的车辆 因此 如果您查看下面的代码 我会在阈值处理和膨胀后找到图像的轮廓 然后我使用 drawContours 和矩形在检测到的轮廓周围绘制一个框 我试图在 drawCont
  • 使用 ImageResizer 获取图像尺寸的最佳方法

    我正在将现有的 MVC 4 网站从自制用户文件上传切换为在上传时使用 ImageResizer 调整文件大小 我在文档中看到我不应该使用 System Drawing 但我无法找出任何其他获取图像尺寸的方法 尺寸是来自原始图像还是调整大小的
  • 从最大到最小的3个整数

    我是 C 初学者 我使用 编程 使用 C 的原理与实践 第二版 问题如下 编写一个程序 提示用户输入三个整数值 然后以逗号分隔的数字顺序输出这些值 如果两个值相同 则应将它们排列在一起 include

随机推荐