DrawImage медленный, локбиты на помощь?
Я читал много руководств по C# по использованию битов блокировки для манипулирования изображениями, но я просто не знаю, как применить эту информацию в powershell.
Это проблема:
Высота $image1 составляет 2950 пикселей. Высота $image2 на 50 пикселей выше, 3000 пикселей. Мне нужно вписать $image2 в $image1, и я могу пропустить первые 49 пикселей строки $image2. Итак, в псевдокоде:
For(y=0... For(x=0.... { image1(x,y) = image2(x,y+50) } ....))
Сценарий powershell ниже работает, но работает не очень быстро:
$rect = new-object Drawing.Rectangle 0, 0, $image1.width, $image1.height
$image1drawing.drawimage($image2,
$rect,
0, 50, $image2.width, ($image2.height - 50),
$graphicalUnit)
Страницы, которые я нашел, такие как эта ( проблема с использованием lockbits) или эта ( http://bobpowell.net/lockingbits.aspx), написаны на "простом английском", но как преобразовать эту концепцию в powershell?
1 ответ
Вы используете правильный подход. С помощью DrawImage
будет быстрее, чем копирование пикселей по одному. Некоторые предложения, чтобы сделать это быстрее:
- Попробуйте использовать Image.Clone, чтобы скопировать прямоугольник из исходного изображения, это приведет к наименьшему количеству объектов, которые вам нужно создать.
- Убедитесь, что вы используете то же самое
PixelFormat
в качестве исходного изображения (более быстрое копирование). E стьPixelFormat
приписыватьImage
, - Самое важное: доступ
Width
а такжеHeight
занимает много времени, поэтому сохраните их в локальной переменной для повторного использования. Если вы знаете их заранее, это хороший способ ускорить процесс. - Не ожидайте чудес при соотношении ширины к высоте 4:3, каждое изображение имеет размер 3932 * 2950 * 3(при условии 24-битного RGB) = 33 МБ на изображение. Это много данных, вы можете легко попытаться скопировать несколько концертов в зависимости от того, сколько изображений у вас есть.
Вам лучше написать простой командлет и использовать его в своем скрипте PowerShell.
Кстати, если вы все еще заинтересованы:
С помощью lockbits
в C# (согласно вашим примерам) опирается на небезопасный контекст и использование указателей. Я не верю, что PowerShell имеет доступ к небезопасному контексту.
Вы можете манипулировать неуправляемыми данными, не используя небезопасный контекст, используя Marshall
учебный класс; конкретно Read
а также Write
методы (и вы могли бы ускорить процесс с Copy
метод за счет памяти).
PowerShell не предназначался для замены универсальных языков.Net, для этого и нужны CmdLets.