abdel hayan Ответов: 4

Как я могу решить проблему сглаживания и битового уменьшения моего изображения


Я хотел бы:
- для придания изображению определенного размера(320х240)
-для изменения цвета до 16 бит 565
-для уменьшения цвета ( 4 бита на пиксель, 16 цветов)

проблема:
Когда я применяю фильтр к bmp-изображению(150 КБ) из (Hexstring 500 КБ): сглаживание и уменьшение цветов с помощью ProcessImageDithering и BitReduction, я пытаюсь сохранить bmp-изображение как image.bmp и получаю очень маленький файл размером 11 КБ(конечно, не желаемое изображение), который обычно должен быть около 250 КБ.
Я действительно не знаю, какую ошибку я сделал, чтобы получить этот результат

I forget to tell you: 
500KB is the hex string of the image(.bmp) so when I apply dithering and bitreduction I try to convert the bitmap to a hex string(stringToTest) and this string paste in a text document in a form (0x45, 0x55 ....) and must have less than 500KB (ex: 250KB) and with this file I could with another program try to build the image to examin it


Что я уже пробовал:

private Bitmap ProcessImageDithering(BitmapImage sourceImage)
        {
            var result = new System.Drawing.Bitmap((int)sourceImage.Width, (int)sourceImage.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);
            
            return result;
        }

private FormatConvertedBitmap BitReduction(ImageSource myBitmapImageFit)
        {
            FormatConvertedBitmap fcb = new FormatConvertedBitmap();
            fcb.BeginInit();
            fcb.Source = myBitmapImageFit as BitmapSource;
            fcb.DestinationFormat = System.Windows.Media.PixelFormats.Indexed4;
            fcb.DestinationPalette = BitmapPalettes.Halftone8;
            fcb.EndInit();
            return fcb;
        }

private void ApplyFilter(string path)
        {
             BootScreen = BootScreenColored;//property of ImageSource
           
            BitmapImage myBitmapImage = new BitmapImage();

            // BitmapSource objects like BitmapImage can only have their properties
            // changed within a BeginInit/EndInit block.
            myBitmapImage.BeginInit();
            if (path == String.Empty)
            {
                //myBitmapImage.StreamSource = new 
                 MemoryStream(this.SelectedFile.BootScreen);//boorscreen is byte[] which contains data of the image
                myBitmapImage.StreamSource = new MemoryStream(ImageSourceToBytes(new BmpBitmapEncoder(), BootScreenColored)); //PngBitmapEncoder
            }
            else
            {
                myBitmapImage.UriSource = new Uri(path);
            }
            myBitmapImage.DecodePixelHeight = (int)HEIGHT;//240
            myBitmapImage.DecodePixelWidth = (int)WIDTH;//320
            myBitmapImage.EndInit();

           

            
            
            
            var result = ProcessImageDithering(myBitmapImage);//Applying  dithering 
                                                              
            //Reduce colors 4 bits per pixel or 16 colors
            var bitmapImage = BitReduction(myBitmapImage);
            //BitmapImage2Bitmap(ByteToBitmapImage(bitmapBytes)).Save(@"C:\_DataFiles\image.bmp");
            var newBitmap = BitmapImage2Bitmap(bitmapImage.Source as BitmapImage);
            byte[] newbytes = BitmapToBytes(newBitmap);
           
            string StringToTest = BitConverter.ToString(newbytes);
        }

4 Ответов

Рейтинг:
28

Patrice T

Цитата:
Я действительно не знаю, какую ошибку я сделал, чтобы получить этот результат.

Первая ошибка заключается в том, что у вас неверные ожидания.
Несжатое растровое изображение размером 320*240 и 16 бит на пиксель получило размер 320*240*2 байты + заголовки, что является схваткой 320*240*2= 153600 байт + заголовки.
С 4 битами на пиксель, это 320*240*0.5= 38400 + заголовки.
Размер делится на 4 без изменения размера.
Таким образом, ожидание 250KB от 500KB подразумевает другие значения или увеличение размера.
Цитата:
Я получаю очень маленький файл размером 11 КБ

Обратите внимание, что bmp также может быть сжат.
Формат файла BMP - Википедия[^]

Вы также забыли сказать, какие характеристики имеет изображение размером 500 КБ.

[Обновление]
Цитата:
Я забыл вам сказать: 500KB-это шестнадцатеричная строка изображения(.bmp), поэтому, когда я применяю сглаживание и битредукцию, я пытаюсь преобразовать растровое изображение в шестнадцатеричную строку(stringToTest), и эта строка, вставленная в текстовый документ в форме (0x45, 0x55....), должна иметь меньше 500KB (например, 250KB), и с помощью этого файла я мог бы с помощью другой программы попытаться построить изображение, чтобы изучить его

Во Франции у нас есть красочная поговорка, которая соответствует тому, что вы сделали: "зачем делать вещи простыми, когда вы можете сделать их сложными ?"
Уменьшение изображения - это не вещь пользовательского интерфейса.
Процедура: входной параметр: имя файла и путь к нему, выходной параметр: имя файла и путь к нему
- Считывание изображения в байтовый массив.
- Примените алгоритм сглаживания и уменьшения цветов к другому массиву байтов.
- Запишите полученный файл.


abdel hayan

Какие характеристики вы имеете в виду?

abdel hayan

у вас есть какие-нибудь предложения?

abdel hayan

Я забыл вам сказать: 500KB-это шестнадцатеричная строка изображения(.bmp), поэтому, когда я применяю сглаживание и битредукцию, я пытаюсь преобразовать растровое изображение в шестнадцатеричную строку(stringToTest), и эта строка, вставленная в текстовый документ в форме (0x45, 0x55....), должна иметь меньше 500KB (например, 250KB), и с помощью этого файла я мог бы с помощью другой программы попытаться построить изображение, чтобы изучить его

Patrice T

Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.

abdel hayan

Я буду его сейчас обновлять
Спасибо

abdel hayan

спасибо, я жду ответа на свой последний вопрос

abdel hayan

реальное изображение(.bmp) составляет 150 КБ

abdel hayan

Я следовал той же процедуре, но она не работает:
Корректны ли процессы Magedithering и BitReduction? Есть какие-нибудь предложения по их улучшению?

Patrice T

каков ваш новый код ?
вы можете открыть новый вопрос.

abdel hayan

Я попытался написать новый вопрос, но он не работает, может быть, потому, что он слишком большой или что-то еще, но я хочу знать, является ли метод dithering to 16 bit color 565 правильным или нет? потому что я прочитал много сложных алгоритмов сглаживания и пытаюсь найти что-то более простое, и поэтому я не уверен в своем решении

abdel hayan

наконец-то я открыл еще один новый вопрос, вы можете его изучить
заранее спасибо

Рейтинг:
24

abdel hayan

Наконец я попробовал это сделать и это работает:
Клонирование растрового изображения в нужный формат

Public void ApplyFilter(string path){
Bitmap myImageResult = BitmapImage2Bitmap(путь);

//Dither до 16 бит на пиксель цвета 565
Растровое изображение DitherTo16Colors = myImageResult.Clone(новый прямоугольник(0, 0, myBitmapImage.DecodePixelWidth, myBitmapImage.DecodePixelHeight), Система.Рисование.Изображений.PixelFormat.Format16bppRgb565);

//Уменьшение цвета (4 бита на пиксель, 16 цветов)
Растровое Изображение ReduceTo4bitsPerPixel = DitherTo16Colors.Clone(новый прямоугольник(0, 0, myBitmapImage.DecodePixelWidth, myBitmapImage.DecodePixelHeight), Система.Рисование.Изображений.PixelFormat.Format4bppIndexed);
}


Рейтинг:
2

Gerry Schmitz

Начните с того, что сделайте "что угодно" , просто "немного" и наблюдайте за изменениями. Когда результаты начнут ухудшаться, скорректируйте переменные соответствующим образом.

Если вы получаете паршивые результаты с самого начала, то переосмыслите весь свой подход.


abdel hayan

Есть ли у вас какие-либо предложения или процедуры, которым вы должны следовать?

abdel hayan

Спасибо Патрис ти и Джерри Шмитц

Рейтинг:
0

abdel hayan

Вот лучший способ уменьшить цвета изображения до 16 цветов (4-битный индексированный).
используя магию.NET-Q16-AnyCPU, который можно загрузить в visual studio с помощью диспетчера пакетов nuget:

private Bitmap MagickReduction(Bitmap bmp)
        {
            Bitmap imageResult = new Bitmap(bmp.Width,bmp.Height);
            using (MagickImage image = new MagickImage(bmp))
            {
                image.ColorType = ColorType.Palette;// set the color type of image
                
                //dithering and number of required colors
                QuantizeSettings settings = new QuantizeSettings
                {
                    DitherMethod = DitherMethod.FloydSteinberg,
                    Colors = 16,
                };
                image.Quantize(settings);
                image.Normalize();//increase contrast 
                imageResult = image.ToBitmap(ImageFormat.Bmp);
            }
            return imageResult;
        }

в настройках вы должны выбрать сколько цветов вы хотите использовать в палитре и квантовать methode сделать волшебную работу за вас