Создание "прозрачного" png-файла

Блог 10 января 2014

Стандартная графическая программа Paint (под Windows) проста и удобна в работе. Существенный недостаток - невозможно сохранить png-файл с прозрачным фоном. Для устранения этого недостатка можно использовать специальную утилиту.

В основе утилиты лежат примеры кода, найденные в сети. Они были адаптированы, и создано консольное приложение на C#.
Работа утилиты контролируется конфигурационным файлом. Там 3 параметра: file - путь к файлу;
thresh - порог, выше которого цвет считается прозрачным;
padding - через запятую размер верхней, правой, нижней, левой зон преобразования (внутри получившейся области преобразование не происходит)
Пример конфигурационного файла.
<?xml 

version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="file" value="C:	emp	est.png"/>
    <add 

key="thresh" value="225"/> <!-- порог для цвета -->
    <add key="padding" value="60,30,40,60"/> <!--top, right, bottom, left: не трогать внутри 

--> 
  </appSettings>
</configuration>
Алгоритм работы утилиты. Создаем имидж на основе файла. Загружаем управляющие параметры. Двигаемся по пикселям имиджа. Делаем пиксель прозрачным при выполнении условий. Сохраняем результат.
using System;



using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Runtime.InteropServices;



using System.Configuration;

namespace PNGmaker
{
    class Program
    {
        static string file, padding;

        static void Main

(string[] args)
        {
            //создать имидж из файла
            file = ConfigurationManager.AppSettings["file"];
            Image 

imageOrig = new Bitmap(file);
            //создать новый имидж на основе оригинального
            Bitmap image = new Bitmap(imageOrig);
            

imageOrig.Dispose();
            //принуждаем имидж иметь прозрачный фон для указанного цвета
            image.MakeTransparent(Color.AntiqueWhite);
       

     //создать графическую область из имиджа
            Graphics g = Graphics.FromImage(image);

            //загрузить thresh
            int thresh 

= 250, top = image.Height, right = image.Width, bottom = image.Height, left = image.Width;
            if (ConfigurationManager.AppSettings["thresh"] != 

null)
                thresh = int.Parse(ConfigurationManager.AppSettings["thresh"]);

            //загрузить padding
            string padd = 

ConfigurationManager.AppSettings["padding"];
            if (padd != null)
            {
                string[] arr = padd.Split(',');
            

    if (arr.Length == 4)
                {
                    top = int.Parse(arr[0]);
                    right = int.Parse(arr[1]);
                  

  bottom = int.Parse(arr[2]);
                    left = int.Parse(arr[3]);
                }
            }

            // GDI+ return format is 

BGR, NOT RGB.
            //получаем данные имиджа
            BitmapData bmData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), 

ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            int offset = 0;
            int stride = bmData.Stride;
            IntPtr Scan0 = 

bmData.Scan0;

            int bBl = 0, bGr = 0, bRd = 0, bAl = 0;
            int nOffset = stride - image.Width * 4;

            //двигаемся по 

данным имиджа, каждый пиксель - 4 байта
            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; 

x++)
                {
                    if (y >= top && y <= image.Height - bottom &&
                        x >= left && x <= image.Width - right)
 

                   {   //внутри области, пропустить
                        offset += 4;
                        continue;
                    }

    

                //считать байты текущего пикселя
                    bBl = Marshal.ReadByte(Scan0, offset);
                    bGr = Marshal.ReadByte(Scan0, 

offset + 1);
                    bRd = Marshal.ReadByte(Scan0, offset + 2);
                    bAl = Marshal.ReadByte(Scan0, offset + 3);

             

       if (bBl > thresh && bGr > thresh && bRd > thresh)
                    {   //сделать пиксель прозрачным
                        Marshal.WriteByte(Scan0, 

offset, (byte)64);
                        Marshal.WriteByte(Scan0, offset + 1, (byte)128);
                        Marshal.WriteByte(Scan0, offset + 2, 

(byte)192);
                        Marshal.WriteByte(Scan0, offset + 3, (byte)0);  //0 - прозрачность
                    }
                    offset += 

4;
                }
                offset += nOffset;
            }
            image.UnlockBits(bmData); 

            //сохранить результат



            g.Flush();
            image.Save(file, System.Drawing.Imaging.ImageFormat.Png);
        }
    }
}

Теги: C#,программирование,интернет магазин под ключ


Комментарии

yura: 17-03-2014 00:44  

Где пример файла до и ПОСЛЕ работы алгоритма?

Добавить комментарий могут только авторизованные пользователи. Авторизоваться
Комментарий

Оценка





Авторизоваться через https://www.pvobr.ru
Логин
Пароль
Регистрация

Авторизоваться через соцсети
Наверх

интернет магазин под ключ

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