龙4ik
会员
- 已加入
- 2020年10月24日
- 留言内容
- 16
- 编程经验
- Beginner
我的任务是编写一个程序,将图像切成相等的矩形拼图。然后,程序必须解决这个难题,而又不知道它被切成薄片的方式。我写了代码,但是它一次又一次地工作,我可以't understand what problem is. Thank you in advance for any help.
附言该算法将每个片段放置在左上角,并尝试通过边界像素之间的最小差异找到最佳的邻近片段
附言该算法将每个片段放置在左上角,并尝试通过边界像素之间的最小差异找到最佳的邻近片段
自动完成难题:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Puzzles
{
struct PixelColor
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
class Alghoritm
{
private List<int> GetNumbers(List<BitmapSource> list)
{
List<int> numbers = new List<int>();
for (int i = 1; i <= list.Count; i++)
{
if (list.Count % i == 0)
{
numbers.Add(i);
}
}
return numbers;
}
private PixelColor[,] GetPixels(BitmapSource source)
{
if (source.Format != PixelFormats.Bgra32)
source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
int width = source.PixelWidth;
int height = source.PixelHeight;
PixelColor[,] result = new PixelColor[width, height];
source.CopyPixels(result, width * 4, 0, true);
return result;
}
private double GetDifference(PixelColor first, PixelColor second)
{
int dr = Math.Abs(first.Red - second.Red);
int dg = Math.Abs(first.Green - second.Green);
int db = Math.Abs(first.Blue - second.Blue);
int da = Math.Abs(first.Alpha - second.Alpha);
return Math.Sqrt(dr * dr + dg * dg + db * db );
}
private double GetRightDifference(PixelColor[,] left, PixelColor[,] right)
{
double rightDifference = 0;
try
{
if (left.Length != right.Length)
throw new Exception("Щось пішло не так");
for (int i = 0; i < left.GetLength(0); i++)
{
rightDifference += GetDifference(left[i, left.GetLength(1) - 1], right[i, 0]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return rightDifference;
}
private double GetBottomDifference(PixelColor[,] up, PixelColor[,] down)
{
double bottomDifference = 0;
try
{
if (up.Length != down.Length)
throw new Exception("Щось пішло не так і тут");
for (int i = 0; i < up.GetLength(1); i++)
{
bottomDifference += GetDifference(up[up.GetLength(0) - 1, i], down[0, i]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return bottomDifference;
}
private BitmapSource GetRightImage(BitmapSource first, List<BitmapSource> list, ref double totalDifference)
{
double min = Int32.MaxValue;
PixelColor[,] left = GetPixels(first);
BitmapSource next = null;
for (int i = 0; i < list.Count; i++)
{
PixelColor[,] right = GetPixels(list[i]);
double value = GetRightDifference(left, right);
if (min > value)
{
next = list[i];
min = value;
}
}
totalDifference += min;
return next;
}
private BitmapSource GetBottomImage(BitmapSource first, List<BitmapSource> list, ref double totalDifference)
{
double min = Int32.MaxValue;
PixelColor[,] up = GetPixels(first);
BitmapSource next = null;
for (int i = 0; i < list.Count; i++)
{
PixelColor[,] down = GetPixels(list[i]);
double value = GetBottomDifference(up, down);
if (min > value)
{
next = list[i];
min = value;
}
}
totalDifference += min;
return next;
}
private double GetBestCurrentVariant(List<BitmapSource> list, int row,int col, ref BitmapSource[,] bestChoice)
{
BitmapSource bestPiece;
double min = Int32.MaxValue;
for (int j = 0; j < list.Count; j++) //перебір всіх елементів колекції для даної розстановки
{
double total = 0; //показує повну різницю всього малюнку
BitmapSource[,] elements = new BitmapSource[row, col]; //отриманий результат
List<BitmapSource> cash = new List<BitmapSource>(list); //колекція доступних елементів
elements[0, 0] = cash[j];
cash.RemoveAt(j);
for (int irow = 0; irow < row - 1; irow++) // перебір по рядкам
{
for (int icol = 0; icol < col - 1; icol++) //перебір по стовпцям
{
//for(int icas = 0; icas<cash.Count;icas++) //перебір по доступним елементам
//{
//}
bestPiece = GetRightImage(elements[irow, icol], cash, ref total);//отримуємо найкращий правий фрагмент
elements[irow, icol + 1] = bestPiece;//додаємо отриманий фрагмент до результату
cash.Remove(bestPiece);//видаляємо недоступний елемент
}
bestPiece = GetBottomImage(elements[irow, 0], cash, ref total);//отримуємо найкращий нижній фрагмент
elements[irow+1, 0] = bestPiece;//додаємо отриманий фрагмент до результату
cash.Remove(bestPiece);//видаляємо недоступний елемент
}
//додаємо фрагменти до останнього рядка
for (int icol = 0; icol < col - 1; icol++) //перебір по стовпцям
{
bestPiece = GetRightImage(elements[row - 1, icol], cash, ref total);//отримуємо найкращий правий фрагмент
elements[row - 1, icol + 1] = bestPiece;//додаємо отриманий фрагмент до результату
cash.Remove(bestPiece);//видаляємо недоступний елемент
}
if (min > total)
{
bestChoice = (BitmapSource[,])elements.Clone();
min = total;
}
}
return min;
}
public BitmapSource[,] GetBestPuzzleImage(List<BitmapImage> list)
{
List<BitmapSource> bmp = new List<BitmapSource>();
for(int i=0;i<list.Count;i++)
{
BitmapSource temp = (BitmapSource)list[i];
bmp.Add(temp);
}
List<int> numbers = new List<int>(GetNumbers(bmp));
BitmapSource[,] bestChoice = null;
double min = Int32.MaxValue; //значення найменшої різниці малюнку(для визначення найкращого результату)
for (int i = 0; i < numbers.Count;i++)
{
int row = numbers[i]; //кількість рядків
int col = list.Count / row; //кількість стовпців
BitmapSource[,] possibleChoice = new BitmapSource[row,col];
double value = GetBestCurrentVariant(bmp, row, col, ref possibleChoice);
if (min > value)
{
bestChoice = (BitmapSource[,])possibleChoice.Clone();
min = value;
}
}
return bestChoice;
}
}
}