Привет!
Вот мои настройки :
У меня есть приложение ac #, которое извлекает функции из серии изображений.Из-за размера набора данных (несколько тысяч изображений) он сильно распараллелен, поэтому у нас есть высокопроизводительная машина с ssd, которая работает на Windows7 x64 (среда выполнения .NET4), чтобы поднять тяжелую работу.Я разрабатываю его на компьютере с Windows XP SP3 x86 под Visual Studio 2008 (.NET3.5) с Windows Forms - кстати, нет возможности перейти в WPF.
Edit3: Это странно, но, думаю, я наконец узнал, что происходит.Кажется, кодек для формата изображения, который дает разные результаты на двух компьютерах!Я точно не знаю, что там происходит, но декодер на xp-машине дает более вменяемые результаты, чем win7.К сожалению, лучше версия все еще находится в системе x86 XP :(. Я думаю, что единственное решение этого - это изменить формат входного изображения на что-то без потерь, как png или bmp (глупо, я не думаю о формате файлаво-первых:)).
Edit2: Спасибо за ваши усилия.Я думаю, что буду придерживаться реализации конвертера самостоятельно, это не совсем то, что я хотел, но я должен решить это как-то :).Если кто-то читает это, у кого есть какие-то идеи для меня, пожалуйста, дайте мне знать.
Редактировать: В комментариях мне было рекомендовано использовать сторонний lib для этого.Я думаю, что я не прояснил себя достаточно, потому что я действительно не хочу использовать подход DrawImage в любом случае - это просто некорректный быстрый хак, чтобы получить реально работающий new Bitmap(tmp, ... myPixelFormat)
, который, мы надеемся, будет использовать некоторую интерполяцию.Единственное, чего я хочу достичь, - это преобразовать входящее изображение в обычный PixelFormat с некоторой стандартной интерполяцией.
Моя проблема заключается в следующем.Некоторые исходные изображения имеют формат Indexed8bpp jpg , который не очень хорошо сочетается с графическими материалами WinForms.Поэтому в моей логике загрузки изображений есть проверка на наличие проиндексированных изображений, которые преобразуют изображение в формат по умолчанию для моих приложений (например, Format16bpp) следующим образом:
Image GetImageByPath(string path)
{
Image result = null;
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
Image tmp = Image.FromStream(fs); // Here goes the same image ...
if (tmp.PixelFormat == PixelFormat.Format1bppIndexed ||
tmp.PixelFormat == PixelFormat.Format4bppIndexed ||
tmp.PixelFormat == PixelFormat.Format8bppIndexed ||
tmp.PixelFormat == PixelFormat.Indexed)
{
// Creating a Bitmap container in the application's default format
result = new Bitmap(tmp.Width, tmp.Height, DefConf.DefaultPixelFormat);
Graphics g = Graphics.FromImage(result);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// We need not to scale anything in here
Rectangle drawRect = new Rectangle(0, 0, tmp.Width, tmp.Height);
// (*) Here is where the strange thing happens - I know I could use
// DrawImageUnscaled - that isn't working either
g.DrawImage(tmp, drawRect, drawRect, GraphicsUnit.Pixel);
g.Dispose();
}
else
{
result = new Bitmap(tmp); // Just copying the input stream
}
tmp.Dispose();
}
// (**) At this stage the x86 XP memory image differs from the
// the x64 Win7 image despite having the same settings
// on the very same image o.O
result.GetPixel(0, 0).B; // x86: 102, x64: 102
result.GetPixel(1, 0).B; // x86: 104, x64: 102
result.GetPixel(2, 0).B; // x86: 83, x64: 85
result.GetPixel(3, 0).B; // x86: 117, x64: 121
...
return result;
}
Я отследил проблему до (*)
.Я думаю, что InterpolationMode как-то связан с этим, но нет разницы, какие из них я выбираю, результаты все равно различаются при (**)
на двух системах.Я исследовал данные тестовых изображений с некоторыми глупыми линиями копирования и вставки, чтобы убедиться, что нет проблем с неправильным доступом к данным.
Все вместе изображения выглядят так: Диаграмма дифракции электронного рассеяния назад.Фактические значения цвета слегка различаются, но они несут много информации - интерполяция даже усиливает ее.Похоже, что алгоритм компоновки на машине x86 использует свойство InterpolationMode, тогда как x64 штуковина просто распределяет значения палитры без учета какой-либо интерполяции.
Я никогда не замечал никакой разницы между выходными данными двух машин до того дня, когда я реализовал функцию просмотра гистограммы для данных в моем приложении.На компьютере x86 он сбалансирован, как и следовало ожидать от просмотра изображений.С другой стороны, машина x64 скорее выдает некую разреженную гистограмму, указывающую на индексированные данные изображения.Это даже влияет на общие выходные данные всего приложения - выходные данные отличаются на обеих машинах с одинаковыми данными, это не очень хорошая вещь.
Для меня это выглядит как ошибка в реализации x64, но это простомне :-).Я просто хочу, чтобы изображения на машине x64 имели те же значения, что и на x86.
Если у кого-то есть идея, я был бы очень рад.Я искал подобное поведение в сети целую вечность, но сопротивление кажется бесполезным:)
О, берегись ... кит!