【问题标题】:Draw border just inside non-transparent portion of image在图像的不透明部分内绘制边框
【发布时间】:2023-04-03 15:15:01
【问题描述】:

这个线程几乎是我需要的: Creating a GraphicsPath from a semi-transparent bitmap

但他正在图像周围绘制轮廓 - 我需要在图像内部绘制一个仅几个像素的轮廓。基本上我正在尝试绘制一个“焦点矩形”(除了它不是矩形) 结果需要采用 GraphicsPath 的形式,以便我可以将其直接放入我当前的代码中。

私有函数GetImagePath(img as Image) as GraphicsPath ... 结束函数

[编辑] 好的,首先我什至无法从其他帖子中获取代码来工作。我一直在这一行得到索引超出范围:

*byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];*

如果它甚至首先通过其他东西。很多时候它从第一个循环中出来并没有找到一个不透明的点 - 当大部分图像是不透明的时候。

最新的问题是它创建了一个没有任何意义的点列表。图像是 68x68,我的点列表有 290x21 之类的点,甚至还有 2316x-15 之类的更疯狂的点

这是我的原图:

[不让我上传,因为我是新的]

它是 70x70 的按钮的背景图像 - 如果这很重要的话。

【问题讨论】:

    标签: .net gdi+ graphicspath


    【解决方案1】:

    我会考虑使用链接中提供的例程,从中获取输出,并在其周围添加您自己的包装器,以修改将其推入您想要的几个像素的路径。您甚至可以在输入参数中设置要移动的像素数量,以便您可以随意使用它。

    否则,您可以将第二遍直接添加到提供的例程中。无论哪种方式,我认为这是一种 2 遍方法。您需要找到对象的外部边界,即提供的内容。然后,您需要自己绕着路径移动,了解路径的导数,以便您可以将路径垂直于您正在查看的当前点的导数移动。您还必须从外部识别内部(即移动线的方向)。

    算法可能看起来像这样(记住只是算法):

    Create New List of Points for the new line
    
    For all points i in 0 to (n-2) (points in original point list)
        // Get a New point in between
        float xNew = (x(i) + x(i + 1) ) / 2
        float yNew = (y(i) + y(i + 1) ) / 2
    
        // Need to figure out how much to move in X and in Y for each (pixel) move along
        // the perpendicular slope line, remember a^2 + b^2 = c^2, we have a and b
        float a = y(i + 1) - y(i)
        float b = x(i + 1) - x(i)
        float c = sqrt( (a * a) + (b * b) )
    
        // c being the hypotenus is always larger than a and b.
        // Lets Unitize the a and b elements
        a = a / c
        b = b / c
    
        // Assume the original point array is given in clockwise fashion
        a = -a
        b = -b
    
        // Even though a was calculated for diff of y, and b was calculated for diff of x
        // the new x is calculated using a and new y with b as this is what gives us the
        // perpendicular slope versus the slope of the given line
        xNew = xNew + a * amountPixelsToMoveLine
        yNew = yNew + b * amountPixelsToMoveLine
    
        // Integerize the point
        int xListAdd = (int)xNew
        int yListAdd = (int)yNew
    
        // Add the new point to the list
        AddPointToNewPointList(xListAdd, yListAdd)
    
    Delete the old point list
    

    我正在执行的几何图形:

    【讨论】:

    • 哇 - 出乎我的意料。我只是让它不画焦点。这样就好了。感谢您的宝贵时间。
    • 我已经编辑了原始帖子,更详细地说明了我在这方面的位置
    • 您是否也拒绝接受我的回答?这个答案是正确的,我试图不重复另一个答案中的内容。如果该代码不起作用,则对这些答案投反对票。我会继续提供帮助。我上面的猜测是图像类型以某种方式没有被正确读取。您可以在打开并读入后尝试检查图像大小。从调试的角度尝试,从每个像素打印出 RGBA 值,同时打印出它们的 XY 坐标,这样您就可以找出他们的算法出了什么问题。
    • 我没那么聪明。我不会做代数,所以我也不会写代码来做。谢谢你的帮助。实际上,我最终找到了一种完全不同的方法。我根本没有在图像上画画。至于这个答案是正确的——如果你这么说的话;)我不能很好地理解它以了解其中的区别。
    • 我很想听听您解决问题的方法:-)
    猜你喜欢
    • 2015-03-28
    • 2013-01-31
    • 2019-02-10
    • 2019-09-10
    • 2011-03-14
    • 2016-08-02
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多