Алгоритм оптимизации работает неправильноC#

Место общения программистов C#
Ответить
Anonymous
 Алгоритм оптимизации работает неправильно

Сообщение Anonymous »


Мне нужно преобразовать пиксельное изображение .png в json. у меня есть структура для этого. Я уже написал рабочий скрипт на .spawn, и он работает правильно. но на C# у меня есть одна из проблем с навыками программирования.

722 пикселя/объекта — на старте. 380 объектов должно быть после оптимизации.

Файл Program.cs:

использование структур; использование System.Drawing; использование System.Drawing.Imaging; использование System.Net; использование System.Runtime.InteropServices; используя System.Text.Json; класс MainClass { общедоступный статический интервал NULL_cnt, COLOR_cnt = 0; общедоступный статический список ? поддон; public static bool Color_exist(Structures.Color Color) { если (палитра == ноль) { pallete = новый список(); палитра.Добавить(Цвет); } foreach (Structures.Color clr в палитре) { if (clr.Equals(Color)) возвращает true; } палитра.Добавить(Цвет); вернуть ложь; } public static int Serch_clr_id (Structures.Color color) { Color_exist (цвет); for (int id = 0; id < pallete.Count; id++) { if (pallete[id].Equals(color)) возвращает идентификатор; } вернуть -1; } public static int Get_block_index_by_pos(float x, float y, блоки Block[]) { Блокировать to_check = null; foreach (блокировать блок в блоках) { if (block.x == x && block.y == y) { to_check = блок; перерыв; } } вернуть блоки.ToList().IndexOf(to_check); } public static Block Get_block_by_pos(блоки с плавающей запятой x, float y, Block[]) { foreach (Блокировать блок в блоках) { if (block.x == x && block.y == y) вернуть блок; } вернуть ноль; } public static int Get_index_by_block (блок блока, блоки блока []) { вернуть блоки.ToList().IndexOf(блок); } public static bool Is_optimizeble (блок блока, блок [] groups_array, размер int, размер img_size) { интервал х = (int)block.x; интервал y = (int)block.y; if (x + размер > img_size.Width || y + size > img_size.Height) возвращает false; for (int X = x; X < x + размер; X++) { for (int Y = y; Y < y + размер; Y++) { Блок to_check = Get_block_by_pos(X, Y,blocks_array); если (to_check == ноль) { вернуть ложь; } если (to_check.color_id != block.color_id) { вернуть ложь; } } } вернуть истину; } public static Block[] Optimize (блоки Block[], размер размера) { // Алгоритм оптимизации List new_blocks =blocks.ToList(); List to_fill = новый List(); логический флаг = ложь; for (int Pixel_size = 4; Pixel_size > 1; Pixel_size - = 2) { Listblocks_to_check = new_blocks; пока (правда) { флаг = правда; //Список local_BTC =blocks_to_check; foreach (блокировать блок в groups_to_check.ToList()) { blocks_to_check.Remove(блок); если (Is_optimizeble(блок, new_blocks.ToArray(), размер пикселя, размер)) { флаг = ложь; плавающий X = блок.x; плавающий Y = блок.y; for (int x = (int)X; x < X + размер_пикселя; x++) { for (int y = (int)Y; y < Y + размер_пикселя; y++) { int to_remove = Get_block_index_by_pos(x, y, new_blocks.ToArray()); if (to_remove != -1) new_blocks.RemoveAt(to_remove); } } логическое условие = размер пикселя == 4; float offset_multipling = условие? 1,5ф: 0,5ф; to_fill.Add(новый блок( состояние ? (int)Block_ID.Full_Pixel : (int)Block_ID.Quadro_Pixel, блок.х + смещение_умножение, блок.y + смещение_умножение, блок.color_id )); перерыв; } } если (флаг) { флаг = ложь; перерыв; } } } return to_fill.ToArray(); } общедоступное статическое преобразование JSON_Image (растровое изображение) { image.RotateFlip(RotateFlipType.RotateNoneFlipY); Размер размер = изображение.Размер; Блоки [] блоки = новый блок [размер.Ширина * размер.Высота]; for (int index = 0; index < size.Width * size.Height; индекс++) { int xPos = индекс % size.Width; int yPos = (int)(индекс/размер.Ширина); Structures.Color curr_color = new Structures.Color(image.GetPixel(xPos, yPos)); блоки[индекс] = новый блок(((int)Block_ID.Pixel), xPos, yPos, Serch_clr_id(curr_color)); } Listblocks_to_check = новый List(); foreach (Блокировать блок в блоках) { if (pallete[block.color_id].a == 0) продолжить; blocks_to_check.Add(блок); } int[] arr_size = new int[2] { size.Width, size.Height }; Console.WriteLine($"{blocks_to_check.Count} LIST\n{blocks.Length} ARRAY"); блоки = Оптимизировать(blocks_to_check.ToArray(), size); Console.WriteLine($"Результат оптимизации: {blocks.Length} блоков"); вернуть новый JSON_Image(arr_size, pallete.ToArray(), блоки); } static void Main(string[] args) { Bitmap img = new Bitmap("C:\\Users\\DENIS\\Desktop\\kris.png", false); строка fileName = "C:\\Users\\DENIS\\Desktop\\kris.json"; строка jsonString = JsonSerializer.Serialize(Convert(img)); File.WriteAllText(имя_файла, jsonString); Console.WriteLine($"{NULL_cnt} {COLOR_cnt}"); } } Структуры.cs

Структуры пространства имен { внутреннее перечисление Block_ID { Пиксель = 917, Квадро_Пиксель = 916, Полный_Пиксель = 955 } внутренний класс Блок { общественный ИНТ obj_id {получить; набор; } общественное плавающее число x {get; набор; } общественное плавающее у {получить; набор; } общественный ИНТ color_id {получить; набор; } общедоступный блок (int OBJ_ID, float X, float Y, int COLOR_ID) { obj_id = OBJ_ID; х = Х; у = Y; color_id = COLOR_ID; } public bool Equals(Блокировать другое) => this.obj_id ==other.obj_id && this.x ==other.x && this.y ==other.y && this.color_id ==other.color_id; } внутренний класс Цвет { общественный ИНТ р {получить; набор; } общественный ИНТ г {получить; набор; } общественный ИНТ б {получить; набор; } общественный ИНТ {получить; набор; } public Color(int R, int G, int B, int A) { г = Р; г = Г; б = Б; а = А; } общедоступный цвет (цвет System.Drawing.Color) { г = цвет.R; г = цвет.G; б = цвет.B; а = цвет.А; } public int[] ToArray() => new int[4] { this.r, this.g, this.b, this.a }; public bool Equals(Color Other) => this.r == Other.r && this.g == Other.g && this.b == Other.b && this.a == Other.a; } внутренний класс JSON_Image { общественный int [] размер {получить; набор; } = новый int[2]; public Array[] Blocks {get; набор; } общественный Array [] Colors_set {get; набор; } public JSON_Image (размер int[], Color[]color_set, блоки Block[]) { this.size = размер; Блоки = новый массив[blocks.Length]; Color_set = новый массив [colors_set.Length]; for (int i = 0; i imgSize[0] || Y + размер > imgSize[1] {вернуть ложь} для x в X..X+размер { для y в Y..Y+размер { let to_check = get_block_by_pos(x, y,blocks_array) если to_check == null {вернуть ложь} if to_check[COLOR] != block_cc { return false } успех_cnt += 1 $.print(succes_cnt / (размер ** 2)) }} вернуть истину } оптимизировать = (объекты){ пусть new_blocks = объекты пусть new_fill_blocks = [] пусть флаг = ложь пусть оптимизирован = {} $.print("Оптимизация количества объектов...") для optim_block_size в 5..2..2 { пусть groups_to_check = new_blocks пусть оптимизировано[@string(optim_block_size)] = 0 пока правда { флаг = правда для блока в groups_to_check { $.print("Осталось проверить: ",blocks_to_check.length) groups_to_check.pop(blocks_to_check.index(блок)) если is_optimizeble (блок, new_blocks, optim_block_size) { флаг = ложь пусть Xpos = блок[X]/gridSize пусть Ypos = блок[Y]/gridSize для x в Xpos..Xpos+optim_block_size { для y в Ypos..Ypos+optim_block_size { let a = new_blocks.index(get_block_by_pos(x, y, new_blocks)) если != ноль { $.print("Удаление блока...") new_blocks.pop(а) }}} пусть fill_offset = 11,25, если optim_block_size == 4, иначе 3,75 пусть заполнение = obj { X: Xpos *gridSize+fill_offset, Y: Ypos * размер сетки + смещение_заполнения, OBJ_ID: 955, если optim_block_size == 4, иначе 916, МАСШТАБИРОВАНИЕ: 1, ВРАЩЕНИЕ: 0, ЦВЕТ: блок[ЦВЕТ] } оптимизированный[@string(optim_block_size)] += 1 new_fill_blocks.push(заполнение) $.print("Готово: ", @string(оптимизировано[@string(optim_block_size)])) $.print("Блоки: ", @string(new_blocks.length + new_fill_blocks.length)) $.print("Заполнение блока в X: ", @string(filling[X]), " | Y: ", @string(fill[Y]), "\n") перерыв } } если флаг == true { флаг = ложь перерыв } } } для блока в new_fill_blocks { new_blocks.push(блок) } $.print("Результаты оптимизации:") для [optSize, optCnt] в оптимизированном { $.print(optSize, "x", optSize, ": ", (@number(optSize) ** 2) * optCnt, " -> ", optCnt) } $.print("Короче: ",blocks.length," -> ",new_blocks.length) $.print("Оптимизировано: ",blocks.length - new_blocks.length,"\n") вернуть новые_блоки } $.print("Чтение JSON...") let data = $.readfile(path + "kris.json", "json") let raw_colors_set = данные['Colors_set'] imgSize = данные['размер'] пусть пиксели = данные['Блоки'] $.print("Готово\n") $.print("Оптимизация цвета...") для цвета в raw_colors_set { if !check_match(rgb8(цвет[0], цвет[1], цвет[2], цвет[3])) { пусть cc = ?c cc.set(rgb8(цвет[0], цвет[1], цвет[2], цвет[3])) каналы_colors_set.push(cc) цвета.push(rgb8(цвет[0], цвет[1], цвет[2], цвет[3])) } } $.print("Готово\n") $.print("Добавление блоков...") для пикселя в пикселях { if raw_colors_set[пиксель[3] - 1][3] != 0 { блоки.push(объект { X: пиксель[1] * размер сетки + смещение, Y: пиксель[2] * размер сетки, OBJ_ID: пиксель[0], ЦВЕТ: каналы_цвета_набор[пиксель[3]] }) } } //смещение += 30 $.print("Готово\n") //блоки = оптимизировать(блоки) $.print("Добавление блоков на уровень...") для блока в блоках { $.add(блок) } $.print("Готово\n") Изображение для конвертации: kris.png

Пожалуйста, я потерял более 6 часов на отладку и ничего не получил.

Я пытался исправить -1 List.Index(блок), ничего Я попытался изменить очередь тайлинга с 4x4 -> 2x2 на 2x2 -> 4x4. И другие вещи, такие как буферы.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»