【问题标题】:Extract a portion of an image in .NET在 .NET 中提取图像的一部分
【发布时间】:2012-12-15 15:32:11
【问题描述】:

我有一张纸牌的 PNG 作为 1 张图像(它将所有 52 张卡片组合成 1 个图像文件)。如何根据需要提取单个卡(或在启动时将它们全部提取到单独的图像文件中)。

我了解知道要获取哪一行和哪一列的逻辑,这是我遇到问题的实际图像处理代码。

我正在使用 Visual Studio 2010 和 VB(尽管任何 .NET 语言的示例代码都可以)。

我不允许发布图片本身,但这是一个示例图片

http://www.jfitz.com/cards/windows-playing-cards.png

谢谢。

【问题讨论】:

  • 请展示一些源代码...你试过什么?究竟是什么不工作?

标签: c# .net vb.net image playing-cards


【解决方案1】:

这将加载原件并创建一个从 (0,0) 开始且尺寸为 100x100 的裁剪版本。您必须编写逻辑来迭代每张卡片,知道何时移动到下一行等。但是,一旦您知道坐标和尺寸,这应该有助于您取出卡片。

Bitmap cards = new Bitmap(@"C:\SomePath\");
Rectangle srcRect = new Rectangle(0, 0, 100, 100);
Bitmap card = (Bitmap)cards.Clone(srcRect, cards.PixelFormat);

顺便说一句,我没有包括对 card.Save() 的调用,因为在保存期间有很多选项需要设置,这有点超出了您的问题范围。但是,有关如何将其保存到磁盘的信息,see http://msdn.microsoft.com/en-us/library/ytz20d80.aspx

【讨论】:

  • 如果有人感兴趣,这里是等效的 VB.NET 代码 Dim cards As Bitmap = New Bitmap("C:\tpm\card_4color.png") Dim srcRect As Rectangle = New Rectangle(0 , 0, 100, 100) Dim card As Bitmap = cards.Clone(srcRect, cards.PixelFormat) 感谢 Scott,代码运行良好。
  • 谁能提供WinRT版本?
【解决方案2】:
public static System.Drawing.Image CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight)
        {
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(cropX, cropY, cropWidth, cropHeight);
            System.Drawing.Image cropped = bitmap.Clone(rect, bitmap.PixelFormat);
            return cropped;
        }

【讨论】:

    【解决方案3】:

    我非常无聊,看看这是否有帮助。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    
    namespace CardDeck
    {
        public class CardCropper
        {
            private Bitmap _source;
            private int _cardsPerRow;
            private int _rowCount;
            private int _cardCount;
            private int _cardWidth;
            private int _cardHeight;
    
            public CardCropper(Bitmap source, int rowCount, int cardsPerRow)
            {
                _source = source;
                _cardsPerRow = cardsPerRow;
                _rowCount = rowCount;
                _cardCount = _cardsPerRow * _rowCount;
                _cardWidth = source.Width / _cardsPerRow;
                _cardHeight = source.Height / _rowCount;
            }
    
            public Bitmap[,] CropCards()
            {
                var cards = new Bitmap[_rowCount, _cardsPerRow];
    
                for (int y = 0; y < _rowCount; y++)
                {
                    for (int x = 0; x < _cardsPerRow; x++)
                    {
                        cards[y, x] = CropCard(x, y);
                    }
                }
    
                return cards;
            }
    
            private Bitmap CropCard(int x, int y)
            {
                var rect = new Rectangle(x * _cardWidth, y * _cardHeight, _cardWidth, _cardHeight);
    
                return _source.Clone(rect, _source.PixelFormat);
            }
        }
    
        public class CardDeck
        {
            private int _limit;
            private int _cardsPerRow;
            private int _index = 0;
            private Bitmap[,] _cards;
    
            public int Index
            {
                get
                {
                    CheckLimits();
                    return _index;
                }
                set
                {
                    _index = value;
                    CheckLimits();
                }
            }
    
            public CardDeck(Bitmap[,] cards, int rowCount, int cardsPerRow)
            {
                _cards = cards;
                _limit = rowCount * cardsPerRow;
                _cardsPerRow = cardsPerRow;            
            }
    
    
            public Image GetCardFromIndex()
            {
                var point = GetPointFromIndex();
    
                return _cards[point.Y, point.X];
            }
    
            private void CheckLimits()
            {
                if (_index >= _limit)
                {
                    _index = 0;
                }
    
                if (_index < 0)
                {
                    _index = _limit - 1;
                }
            }
    
            private Point GetPointFromIndex()
            {
                int x = this.Index % _cardsPerRow;
                int y = this.Index / _cardsPerRow;
    
                return new Point(x, y);
            }
        }
    }
    

    用法:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace CardDeck
    {
        public partial class CardDeckForm : Form
        {
            private CardDeck _cardDeck = null;
    
            public CardDeckForm()
            {
                InitializeComponent();
    
                LoadCards();
    
                ShowImage();
            }
    
            private void LoadCards()
            {
                using (var source = new Bitmap(@"AllCards.png"))
                {
                    var cards = new CardCropper(source, rowCount: 4, cardsPerRow: 13).CropCards();
                    _cardDeck = new CardDeck(cards, rowCount: 4, cardsPerRow : 13);
                }
            }
    
            private void NextButton_Click(object sender, EventArgs e)
            {
                _cardDeck.Index++;
                ShowImage();
            }
    
            private void PreviousButton_Click(object sender, EventArgs e)
            {
                _cardDeck.Index--;
                ShowImage();
            }
    
            private void ShowImage()
            {
                this.cardPictureBox.Image = _cardDeck.GetCardFromIndex();
            }
        }
    }
    

    【讨论】:

    • 我的意思是他们由 OP 来衡量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2020-10-08
    • 2014-04-22
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多