Стандартная
графическая программа 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);
}
}
}