РЕДАКТИРОВАТЬ:
Вы можете решить проблему неизменяемого растрового изображения при загрузке из файла следующим образом:
var bmp = new Bitmap(Image.FromFile("C:\bmp.bmp"))
Это предотвращает необходимость выполнения Marshal.Copy (которые выполняются медленно), а также решает проблему искажения и искажения GIF-файлов. Внутренний код .NET, который делает это, если вам интересно, следующий:
g = Graphics.FromImage(this);
g.Clear(Color.Transparent);
g.DrawImage(original, 0, 0, width, height);
так что по сути это код, который я дал вам ниже, для решения проблемы прозрачности, которая не отвечала вашим потребностям в скорости.
Однако, если вы можете одновременно выполнять загрузку и копирование через g.FromImage, я получаю скорости (5.6 seconds g.FromImage vs 6.4 seconds yours with 1000 gifs @ 543x341)
Теоретически вы можете сделать свое дело быстрее, если объедините копирование и удаление прозрачности в одной функции. Если вы загрузите GIF без перезаписи изображения, оно будет в другом пиксельном формате, на самом деле, 8bppindexed
, что означает, что ваша функция не будет работать как есть. В любом случае, приведенное выше решение решит проблему при использовании вашей функции CheckIfTransparent, а решение ниже (мне пришлось немного отредактировать) сделает это быстрее. Я могу потратить некоторое время на поиски этого, если сделаю. Я нахожу проблему интересной.
Я заметил, что ваш алгоритм удаления альфы не совсем точен. Я не уверен, где именно, но ваш алгоритм выглядит неправильно при использовании с прозрачными градиентами. Тот, который использует прямой GDI, выглядит как и ожидалось. Я бы убедился, что вы правильно конвертируете цвета.
Если вы просто хотите удалить прозрачность в png или gif, сделав все это Marshal.Copy
и небезопасный код, почему бы просто не создать новое растровое изображение, нарисовать белый фон, а затем наложить выходящий png / gif на Это? Похоже, менее сложный код.
РЕДАКТИРОВАТЬ: Примерно так:
public static Bitmap ManagedSafeBitmap(string file)
{
using (var img = Image.FromFile(file))
{
var bmp = new Bitmap(img.Width, img.Height);
bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
g.DrawImage(img, 0, 0);
}
return bmp;
}
}
Это даст вам новое изображение с белым фоном и поместит исходное изображение поверх него, эффективно изменив все прозрачные пиксели на Color.White
или любой цвет, который вы хотите передать g.Clear()