我有一副牌的PNG作为1张图像(它将所有52张卡合并为1张图像文件)。如何在需要时提取单个卡(或在启动时将它们全部提取到单独的图像文件中)。
我理解知道要获取哪一行和哪一行的逻辑,它是我遇到问题的实际图像处理代码。
我正在使用Visual Studio 2010并使用VB(尽管任何.NET语言中的示例代码都可以)。
我不允许发布图像本身,但这是一个示例图像
http://www.jfitz.com/cards/windows-playing-cards.png
感谢。
答案 0 :(得分:6)
这将加载原件并创建一个从(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。
答案 1 :(得分:0)
我非常无聊,看看这是否有帮助。
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();
}
}
}
答案 2 :(得分:0)
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;
}