Ну, существует плагин PSD для Paint.NET, который я думаю, Открытый исходный код, на который Вы могли бы хотеть смотреть для начинающих:
http://frankblumenberg.de/doku/doku.php?id=paintnet:psdplugin#download
Еще более быстрый способ - использовать таблицы поиска. Поскольку вы знаете, что все значения имеют интенсивность от 0 до 255, вы создаете двоичный эквивалент каждого, чтобы ускорить процесс.
% build table (computed once) [using gnovice option#1]
lookupTable = cell2mat(arrayfun(@(i)bitget([0:255]',9-i),1:8,'UniformOutput',0));
% random' image
I = randi(256, [240 320])-1;
% decimal to binary conversion
binI = lookupTable(I(:)+1,:);
На моей машине это заняло в среднем 0,0036329 секунды (только преобразование). Обратите внимание, что в таблице поиска почти нет служебного места:
>> whos lookupTable
Name Size Bytes Class Attributes
lookupTable 256x8 2048 uint8
Разве вы не можете использовать bitand для получения битов напрямую?
s(0) = 256 bitand input
s(1) = 128 bitand input
s(2) = 64 bitand input
и т. Д.
Вы можете перебрать каждый пиксель (или значение RGB) в своем изображении и использовать BITGET , чтобы получить вектор нулей и единиц. Вот пример использования BITGET:
>> bitget(uint8(127),8:-1:1) % Get bits 8 through 1 for a uint8 value
ans =
0 1 1 1 1 1 1 1
Можно создать векторизованное решение, в котором вы перебираете каждый бит вместо каждого пикселя , выполняя операцию BITGET для всей матрицы изображения каждый раз в цикле. Ниже приводится одна из таких реализаций:
function B = get_bits(A,N)
% Gets the N lowest bits from each element of A
B = zeros([size(A) 0]);
nDims = ndims(A)+1;
for iBit = N:-1:1
B = cat(nDims,B,bitget(A,iBit));
end
end
Если матрица A
является 2-мерной (n-на-m) или 3-мерной (n-на-m-by-p), матрица B
будет на одно измерение больше. Дополнительное измерение будет иметь размер N
с наивысшим битом в индексе 1. Вы можете проиндексировать это измерение, чтобы получить битовое значение, или преобразовать B
в более легко визуализируемую форму. Вот пример использования:
>> A = uint8([126 128; 127 129]); % A 2-by-2 matrix of uint8 values
>> B = get_bits(A,8); % B is a 2-by-2-by-8 matrix
>> B(:,:,1) % Get bit 8 for each value in A
ans =
0 1
0 1
>> reshape(B,4,8) % Reshape B into a 4-by-8 matrix
ans =
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 1
This kind of problem (perform a per-element operation on a large array, because Matlab's built-in code is too slow) sometimes calls for a solution in Java, since Matlab runs on a JRE and converting/passing array arguments is usually a fairly fast operation.
gnovice's solution sounds like it works for you, but if you run into a situation you can't solve in pure Matlab, and you're proficient in Java, consider writing a custom JAR file. It's pretty easy. (well, a whole lot easier than trying to interface C++ to Matlab!)