Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.11;
Скачать: CL | DM;

Вниз

Алгоритм преобразования монохромного изображения   Найти похожие ветки 

 
Штотоносец   (2005-03-11 20:28) [0]

Не знаю как точно сказать. Вообщем есть монохромное изображение и надо его преобразовать в 2, 4, 8 и т.д. цветное, т.е. градацией серого. Во. Вроде понятно объяснил :)


 
Virgo_Style ©   (2005-03-11 20:31) [1]

Осредняй значение яркости в некоторой области каждой точки, нормируй... И смотри, в какой диапазон попадает...


 
YurikGL ©   (2005-03-11 20:31) [2]

Чего во что преобразовать то надо? Цветное->монохромное или монохромное->цветное? Вророе, вроде как, нельзя. А первое - формулу я как-то яндексом в свое время нашел...


 
TUser ©   (2005-03-11 20:32) [3]

Не не понятно.
В монохромном изображении размера n*m есть m*n бит информации. Ты хочешь преобразовать его в изображение того же размера, но большей цветности, так? Там информации больше. Откуда брать занчения дополнительных бит.


 
YurikGL ©   (2005-03-11 20:32) [4]

тьфу... прочитал

> 2, 4, 8 и т.д. цветно"е

по науке, делается это методами кластеризации...


 
YurikGL ©   (2005-03-11 20:33) [5]


> Штотоносец   (11.03.05 20:28)  

можно поискать как Image-ready гифы делает...


 
Штотоносец   (2005-03-11 20:37) [6]

Нет не цветное, а как бы серое 8\ Всмысле если двухцветное, то это черный и белый, если 4, то белый, черный и две градации серого. Всего, максимально, какбы 256 градаций. Изображение-то монохромное, т.е. серое и то, что колор получить никак я понимаю, вообщем это и не надо.


 
YurikGL ©   (2005-03-11 20:49) [7]

Тебе нужны методы кластеризации.
Кратко, суть в том, что произвольное множество точек делится на заранее заданное (в твоем случае) количество "сгущений". Результатом применения метода будут центры "сгущений". Дальше, вычисляя расстояние между конкретной точкой и центрами "сгущений" заменяем эту точку центром ближайшего "сгущения". Не уверен, что эти методы можно в инете нарыть, на на лабах такие рассчеты мы делали.


 
Штотоносец   (2005-03-11 21:01) [8]

Да уж, мудрено. А может у кого завалялся исходничек?


 
Virgo_Style ©   (2005-03-11 21:02) [9]


> Да уж, мудрено

Мне тоже так показалось :-) А чем [1] не устраивает?


 
Штотоносец   (2005-03-11 21:05) [10]

Так там, помоему, еще мудреней :)


 
YurikGL ©   (2005-03-11 21:09) [11]


> А чем [1] не устраивает?


есть у тебя картинка, где реально используются цвета
0,1,2,10,11,12,230,231,232,250,251,252.
Нужно к 4-м цветам преобразовать на основании чего будещ диапазоны цветов выбирать?


 
Virgo_Style ©   (2005-03-11 21:50) [12]

Да, я, кажется, неправ :-) Это для Черный+Белый -> градации серого, а вопрос, как я теперь понял, о снижении цветности? Тогда молчу :-)


 
TUser ©   (2005-03-11 21:50) [13]


> YurikGL ©

я понимаю - тут обратная задачав. воссановить информацию из изображения, где эта инфа потеряна. низя ...


 
Virgo_Style ©   (2005-03-11 22:11) [14]

TUser ©   (11.03.05 21:50) [13]
Хм. Автор! Объясните народу - информацию надо потерять или найти? Градации серого - в меньшее количество градаций серого, или же B&W - в градации?
:-)


 
Штотоносец   (2005-03-11 23:52) [15]

Так, попробую. В ПАМЯТИ хранится изображение. Монохромное - 256 градаций. В зависимости от положения бегунка, на форму выводится изображение преобразованное с оригинала (в памяти). Поэтому восстановление потерянной информации не подразумевается из-за отсутствие таковой =)


 
XProger ©   (2005-03-12 04:30) [16]

Штотоносец, дык тебе уменьшение кол-ва байт на пиксель нужно? ;)


 
XProger ©   (2005-03-12 04:31) [17]

т.е. бит?
Допустим было изображение 8 бит на киксель урезали стало 7 бит ... 1 бита на пиксель. С потерей качества разумеется.


 
Fenik   (2005-03-12 12:05) [18]

Ты в баню?
Нет, я в баню.
Ааа, я думал, что ты в баню.


 
Штотоносец   (2005-03-12 13:19) [19]

Допустим есть изображение, у которого каждый Image2.Canvas.Pixels[w,h] равен некоему колору, в момнохроме от 0..255, точнее например RGB(0,0,0), это черный, а RGB(255,255,255), это белый.
Понятно, что если просто уменьшать это значение, то при двухцветности, рисунок станет просто черным, да это будет видно и раньше.

Я понимаю, что YurikGL [7] высказал верную идею, но у меня возникают проблемы с ее реализацией, точнее на проблемы, а я не знаю даже как начать.


 
Virgo_Style ©   (2005-03-12 15:08) [20]

Самое дубовое решение - разбить диапазон 0..255 на поддиапазоны в нужном количестве. Например
0..128   - это цвет (0+128)/2
128..255 - это цвет (128+255)/2
Куда попадает твой серый - тем цветом он и станет.
Чуть менее дубовое - считать средний цвет для каждого диапазона.
Но это все равно дубово, а если надо хорошо - тогда [7]


 
Штотоносец   (2005-03-12 15:13) [21]

К сожалению мне надо уехать, а буду я в воскресенье вечером, тогда и продолжим.


 
Fenik   (2005-03-12 19:38) [22]

Ладно уж, даю грубый вариант:


procedure SetGrayScale(Bitmap: TBitmap; Value: Byte);
var Pixel: pRGBTriple;
   x, y, n: Integer;
   A: array [Byte] of Byte;
begin
 if Value > 1 then begin
   A[0] := 0;
   A[255] := 255;
   for x := 1 to 254 do begin
     case Value of
       2: A[x] := Byte(x>127)*255;
       3..127: begin
         n := Round(256/(Value-1));
         n := Round(x/n)*n;
         if n <= 255 then A[x] := n
                     else A[x] := 255;
       end;
       else A[x] := x;
     end;
   end;
 end
 else
   FillChar(A, SizeOf(A), 0);
   
 for y := 0 to Bitmap.Height - 1 do begin
   Pixel := Bitmap.ScanLine[y];
   for x := 0 to Bitmap.Width - 1 do begin
     with Pixel^ do begin
       rgbtBlue  := A[rgbtBlue];
       rgbtGreen := A[rgbtGreen];
       rgbtRed   := A[rgbtRed];
     end;
     Inc(Pixel);
   end;
 end;
end;


 
Fenik   (2005-03-12 20:04) [23]

Забыл:
n := Round(256/(Value-1));
можно вынести из цикла :)


 
Штотоносец   (2005-03-14 18:16) [24]

У меня по YurikGL [7] получилось следующее;

procedure Tfrm_Main.GetGrayScale(Value:Integer);
var
 i,w,h:integer;
 a,c:Real;
 b:byte;
begin
 w:=0;
 h:=0;
 if value<>256 then a:=256/value;
 for i:=1 to Length(ArrByteImg) do begin
   b:=ArrByteImg[i-1];
   if value<>256 then begin
     c:=Ceil(b/a);
     if (b-a*c)>(a/2) then c:=Floor(b/(a+1));
     b:=Round(c*a);
     if (b=0) and (c<>0) then dec(b);
   end;
   Image2.Canvas.Pixels[w,h]:=b shl 16 + b shl 8 + b;
   inc(w);
   if w=Image2.Width then begin
     w:=0;
     inc(h);
   end;
 end;
end;


Единственная проблема в то, что при 2-х цветности получаются 128 и 255, т.е. белый и серый, а не черный.
Посмотрите пожалуйста в чем проблема.

Да, вот еще. ArrByteImg это ArrByteImg:array of byte;

 a:=0;
 SetLength(ArrByteImg,Image2.Height*Image2.Width-1);
 for h:=0 to Image2.Height-1 do begin
   for w:=0 to Image2.Width-1 do begin
     ArrByteImg[a]:=GetRValue(Image2.Canvas.Pixels[w,h]);
     inc(a);
   end;
 end;


 
Fenik   (2005-03-14 19:13) [25]

Это че за лабуда? :))
Я тебе процедуру дал? Дал.
Ты скорость работы сравнивал со своим произведением? Сомневаюсь.
Короче, не парься и возьми мою функцию. Правь в ней первоначальное заполнение массива по своему усмотрению и всё. Для двух цветов там как тебе надо работает.
Не забудь только Bitmap.PixelFormat := pf24Bit;


 
Штотоносец   (2005-03-14 19:24) [26]

Fenik [25]
Послушай, я не лабы пишу и мне завтра это не здавать, я для себя пишу, так сказать для общего развития, поэтому хочеться самому =)
Если хочешь помочь, так лучше укажи на ошибки, объясни, если не влом, а то; "Это че за лабуда?". Ты типа лох, я тебе все дал, а ты типа, даже просто код скопировать не можешь. Так можно инерпретировать твои слова. А это обидно.


 
Fenik   (2005-03-14 19:34) [27]

Прости, не хотел обидеть. Там вообще-то смайлы.. :)
Вместо Canvas.Pixels целесообразней использовать ScanLine. Это первое. (Выигрыш в скорости офигенный)
А второе - это че за лабуда? :))))) Шутю.
Ты можешь объяснить, зачем тебе понадобилсся какой-то массив пикселей ArrByteImg?
Вообще прокомментируй свой код.
Потом посмотри внимательно на мой и подумай, что в нем тебе не понятно. Короче - смотри, думай и спрашивай.


 
dmk ©   (2005-03-14 21:23) [28]

Вот тебе еще немного кода. Преобразование BiLevel в Grayscale.
Преобразует 8 BiLevel-строк в 1 Grayscale.
Кстати! Потрясная скорость!

Только для этого надо сначала подсчитать
кол-во бит в кубике 8х8 и занести их в массив из
которого эта процедура выборку делает.
Я делаю это в секции Initialization

function Bit(TestByte, TestBit:Integer):boolean;
asm
  bt    eax, edx
  setc  al
  and   eax, 0FFh
end;

Function BitsCount(v:byte):byte;
var
 c:    Byte;
 res:  Integer;
 
begin
Res := 0;

For c := 0 to 7 do If Bit(v,c) then Inc(Res, 32);

If Res > 255 then Res := 255;
Result := Byte(Res);
end;

procedure InitHalphtoneBits;
var
 Counter:Byte;

begin
 For Counter := 0 to 255 do HBitsArray[Counter] := BitsCount(Counter);
 HBitsArray[0] := 0;
 HBitsArray[255] := 255;
 HBitsArrayAddr := DWord(Addr(HBitsArray[0])); //&#204;&#224;&#241;&#241;&#232;&#226; &#239;&#238;&#228;&#241;&#247;&#232;&#242;&#224;&#237;&#237;&#251;&#245; &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#233;
end;

procedure TImageStream.HalftoneLine(InputAddress, OutputAddress, Len:DWord);
var
 FStart:       DWord;
 FPos:         DWord;
 FNewStart:    DWord;
 FNewPos:      DWord;

 //...
 FLineSize:    DWord;
 FLinePos:     DWord;

 //...
 FSum:         DWord;
 FHMem:        DWord;

begin
 FStart        := InputAddress;
 FHMem         := HBitsArrayAddr; //&#204;&#224;&#241;&#241;&#232;&#226; &#239;&#238;&#228;&#241;&#247;&#232;&#242;&#224;&#237;&#237;&#251;&#245; &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#233;
 FLineSize     := Len;

 //...
 FNewStart     := OutputAddress;
 FNewPos       := 0;
 FPos          := 0;

 //...
 asm
      push       edi
      push       esi
      push       ebx

      mov        edx, FStart           {&#205;&#224;&#247;&#224;&#235;&#252;&#237;&#251;&#233; &#224;&#228;&#240;&#229;&#241; &#226; bitmap &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;}
      add        edx, FPos             {&#207;&#238;&#231;&#232;&#246;&#232;&#255; &#226; bitmap &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;}
      mov        edi, FNewStart        {&#205;&#224;&#247;&#224;&#235;&#252;&#237;&#251;&#233; &#224;&#228;&#240;&#229;&#241; &#226; grayscale &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;}
      add        edi, FNewPos          {&#207;&#238;&#231;&#232;&#246;&#232;&#255; &#226; grayscale &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;}
      mov        esi, FHMem            {&#209;&#242;&#224;&#240;&#242;&#238;&#226;&#251;&#233; &#224;&#228;&#240;&#229;&#241; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; &#239;&#238;&#228;&#241;&#247;&#232;&#242;&#224;&#237;&#237;&#251;&#245; &#231;&#237;&#224;&#247;&#229;&#237;&#232;&#233;}
      mov        ecx, FLineSize        {&#228;&#235;&#232;&#237;&#224; &#241;&#234;&#224;&#237;-&#235;&#232;&#237;&#232;&#232;}
      mov        ebx, ecx
      mov        FLinePos, 0

@@Cyc: mov        FSum, 0
      xor        eax, eax

   {0}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx, ebx

   {1}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {2}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {3}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {4}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {5}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {6}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax
      add        edx,ebx

   {7}mov        al, [edx]
      mov        al, [esi+eax]
      add        FSum, eax

      mov        eax, FSum
      shr        ax, 3

      mov        [edi], al  //&#199;&#224;&#239;&#232;&#241;&#252; &#241;&#243;&#236;&#236;&#251; &#226; grayscale &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#229;
      inc        edi

      mov        edx, FStart  //&#200;&#241;&#245;&#238;&#228;&#237;&#251;&#233; &#224;&#228;&#240;&#229;&#241;
      add        edx, FPos
      inc        FLinePos
      add        edx, FLinePos

      loop       @@Cyc
      //...
      pop        ebx
      pop        esi
      pop        edi
     end;

end;


 
Fenik   (2005-03-14 21:33) [29]

Ну всё, завалили парня кодом :)))


 
YurikGL ©   (2005-03-14 21:33) [30]


> Fenik   (12.03.05 19:38) [22]

Я в [11] пример привел, который методом деления "в лоб" не решается.

Автору:
Посмотри http://www.megaputer.ru/content/production/pa/_polyanalyst_info.html#5_05

Алгоритм кластеризации в твоем случае, примерно такой:
Пусть нам надо представить все в 4-х цветах. Тогда, делим всю область пополам т.е. цвета меньше 127,5 и больше 127,5 т.е. граница между двумя кластерами будет 127.5. Далее сдвигаем эту границу в сторону с большим количеством точек до тех пор, когда точек с обоих сторон не станет поровну. Далее, каждый получившийся кластер делим аналогичным способом пополам. После этого у нас в каждом из 4-х кластеров поровну точек (или почти поровну). Берем за новые цвета средние арифметические значений точек в каждом кластере и заменяем точки каждого кластера полученным значением.

Конечно, будут и пограничные значения и разное количество точек в кластерах, но общий алгоритм может быть такой. Ситуацию [11] он должен обработать корректно. Хотя существуют ситуации, которые и этот алгоритм обработает некорректно. Например значения
1,1,1,1,1,1, 200,201,202. разделить на 4 цвета. Для учета таких ситуаций надо еще много чего считать.

Хотя в университете нам вроде давали гораздо более оптимальные алогоритмы, но это надо в лекциях рыться :-)


 
Fenik   (2005-03-14 21:40) [31]

>YurikGL ©  (14.03.05 21:33) [30]
>Я в [11] пример привел, который методом деления "в лоб" не решается.

Я понимаю и полностью поддерживаю.
Поэтому и написал "грубый вариант". Просто как пример.


 
dmk ©   (2005-03-14 21:58) [32]

А если хочешь с RGB работать, что крайне непонятно для меня,
сначала конвертни Bitmap-строку в RGB. Также сначала
создай RGB-представление битов.

//&#207;&#240;&#238;&#246;&#229;&#228;&#243;&#240;&#224; &#241;&#238;&#231;&#228;&#224;&#229;&#242; &#236;&#224;&#241;&#241;&#232;&#226; &#238;&#242;&#238;&#225;&#240;&#224;&#230;&#224;&#254;&#249;&#232;&#233; &#225;&#232;&#242;&#251; &#226; RGB &#239;&#240;&#229;&#228;&#241;&#242;&#224;&#226;&#235;&#229;&#237;&#232;&#232;
//&#207;&#240;&#232;&#236;&#229;&#240;: (10001111) = ($00000000 $00FFFFFF $00FFFFFF $00FFFFFF $00000000 $00000000 $00000000 $00000000)
//&#200;&#241;&#239;&#238;&#235;&#252;&#231;&#243;&#229;&#242;&#241;&#255; &#228;&#235;&#255; &#239;&#240;&#238;&#240;&#232;&#241;&#238;&#226;&#234;&#232; &#239;&#240;&#232; &#225;&#232;&#242;&#237;&#238;&#241;&#242;&#232; 1 Bpp
//&#204;&#224;&#241;&#241;&#232;&#226; &#231;&#224;&#237;&#232;&#236;&#224;&#229;&#242; 8&#202;&#225;
Procedure TImageStream.InitRgbMapOfBits;
var
 Counter:      Byte; //&#209;&#247;&#229;&#242;&#247;&#232;&#234; &#225;&#224;&#233;&#242;&#238;&#226;
 bc:           Byte; //&#209;&#247;&#229;&#242;&#247;&#232;&#234; &#225;&#232;&#242;&#238;&#226;

begin
 For Counter := 0 to 255 do
   begin
     For bc := 0 to 7 do
       If Bit(Counter, bc) then
          FRGBBitsArray[Counter].Cell[7 - bc] := clWhite else
          FRGBBitsArray[Counter].Cell[7 - bc] := clBlack;
   end;

 //&#192;&#228;&#240;&#229;&#241; &#237;&#224;&#247;&#224;&#235;&#224; &#236;&#224;&#241;&#241;&#232;&#226;&#224;
 FRGBBitsAddr := DWord(Addr(FRGBBitsArray[0].Cell[0]));
 RgbBits := FRgbBitsAddr;
end;


 
dmk ©   (2005-03-14 22:02) [33]

Procedure ConvertBitmapScLineToRgb(ImgLineAddr:DWord; DBufferLineAddr:DWord; NumberBits:DWord; StartBit:Byte);
var
 SrcAddr:            DWord;
 DestAddr:           DWord;
 BitsOffs:           DWord; //&#209;&#236;&#229;&#249;&#229;&#237;&#232;&#229; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; RGBBits
 FBitsLen:           DWord; //&#196;&#235;&#232;&#237;&#224; &#234;&#238;&#239;&#232;&#240;&#243;&#229;&#236;&#238;&#233; &#255;&#247;&#229;&#233;&#234;&#232;
 FBitsStart:         DWord; //&#205;&#224;&#247;&#224;&#235;&#238; &#226; &#255;&#247;&#229;&#233;&#234;&#229;
 FTotalBits:         DWord;
 FFirstBitsLen:      DWord;
 FLastBitsLen:       DWord;
 FBitsForCycle:      DWord;

begin
   //&#192;&#228;&#240;&#229;&#241; &#241;&#234;&#224;&#237;-&#235;&#232;&#237;&#232;&#232; &#226; &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;
   SrcAddr := ImgLineAddr;

   //&#192;&#228;&#240;&#229;&#241; &#241;&#234;&#224;&#237;-&#235;&#232;&#237;&#232;&#232; &#226; &#234;&#238;&#237;&#229;&#247;&#237;&#238;&#236; &#225;&#243;&#244;&#229;&#240;&#229;
   DestAddr := DBufferLineAddr;

   //&#202;&#238;&#235;-&#226;&#238; &#225;&#232;&#242;&#238;&#226; &#226; &#241;&#234;&#224;&#237;-&#235;&#232;&#237;&#232;&#232;
   FTotalBits := NumberBits;

   //&#208;&#224;&#241;&#247;&#229;&#242; &#241;&#236;&#229;&#249;&#229;&#237;&#232;&#255; &#226; &#225;&#224;&#233;&#242;&#229;, &#242;.&#234;. &#239;&#232;&#234;&#241;&#229;&#235;&#252; &#236;&#238;&#230;&#229;&#242; &#237;&#224;&#247;&#232;&#237;&#224;&#242;&#241;&#255; &#226; &#225;&#224;&#233;&#242;&#229; &#227;&#228;&#229; &#243;&#227;&#238;&#228;&#237;&#238;
   FBitsStart := StartBit;

   //&#196;&#235;&#255; &#246;&#232;&#234;&#235;&#224; &#225;&#232;&#242;&#238;&#226; &#237;&#229;&#242;
   FBitsForCycle := 0;

   //&#196;&#235;&#255; &#239;&#238;&#241;&#235;&#229;&#228;&#237;&#229;&#227;&#238; &#225;&#224;&#233;&#242;&#224; &#242;&#238;&#230;&#229; &#237;&#229;&#242;
   FLastBitsLen := 0;

   //&#197;&#241;&#235;&#232; &#228;&#235;&#232;&#237;&#224; &#236;&#229;&#237;&#252;&#248;&#229; &#226;&#238;&#241;&#252;&#236;&#232; &#239;&#232;&#234;&#241;&#229;&#235;&#238;&#226;(&#225;&#224;&#233;&#242;&#224;)
   If FTotalBits < 8 then
     begin
       //&#229;&#241;&#235;&#232; &#237;&#224;&#247;&#224;&#235;&#252;&#237;&#251;&#233; &#225;&#232;&#242; &#237;&#229; &#237;&#243;&#235;&#229;&#226;&#238;&#233;
       If StartBit <> 0 then
         begin
           //&#209;&#247;&#232;&#242;&#224;&#229;&#236;, &#247;&#242;&#238; &#228;&#235;&#232;&#237;&#224; &#246;&#229;&#239;&#238;&#247;&#234;&#232; &#226; &#239;&#229;&#240;&#226;&#238;&#236; &#225;&#224;&#233;&#242;&#229;
           //&#240;&#224;&#226;&#237;&#224; &#238;&#241;&#242;&#224;&#226;&#248;&#232;&#236;&#241;&#255; &#225;&#232;&#242;&#224;&#236;
           FFirstBitsLen := 8 - StartBit;
           //&#205;&#243; &#224; &#229;&#241;&#235;&#232; &#228;&#235;&#232;&#237;&#224; &#238;&#241;&#242;&#224;&#226;&#248;&#232;&#245;&#241;&#255; &#225;&#232;&#242;&#238;&#226;
           //&#236;&#229;&#237;&#252;&#248;&#229; &#228;&#235;&#232;&#237;&#251; &#226;&#245;&#238;&#228;&#237;&#238;&#233; &#246;&#229;&#239;&#238;&#247;&#234;&#232;
           //&#242;&#238; &#241;&#225;&#240;&#224;&#241;&#251;&#226;&#224;&#229;&#236; &#228;&#235;&#232;&#237;&#243; &#239;&#229;&#240;&#226;&#238;&#233; &#246;&#229;&#239;&#238;&#247;&#234;&#232;
           //&#234; &#226;&#245;&#238;&#228;&#237;&#238;&#236;&#243; &#234;&#238;&#235;-&#226;&#243;
           If FFirstBitsLen > FTotalBits then FFirstBitsLen := FTotalBits;
           //&#197;&#241;&#235;&#232; &#234;&#238;&#235;-&#226;&#238; &#225;&#232;&#242;&#238;&#226; &#226; &#239;&#229;&#240;&#226;&#238;&#236; &#225;&#224;&#233;&#242;&#229;
           //&#236;&#229;&#237;&#252;&#248;&#229; &#247;&#229;&#236; &#226;&#241;&#229;&#227;&#238;, &#242;&#238;
           //&#239;&#240;&#238;&#232;&#241;&#245;&#238;&#228;&#232;&#242; &#239;&#229;&#240;&#229;&#245;&#238;&#228; &#226; &#241;&#235;&#229;&#228;&#243;&#254;&#249;&#232;&#233; &#225;&#224;&#233;&#242;
           If FFirstBitsLen < FTotalBits then
             FLastBitsLen := FTotalBits - FFirstBitsLen;
         end//If aX <> 0 then
        else
         begin
           //&#196;&#235;&#232;&#237;&#224; &#239;&#229;&#240;&#226;&#238;&#233; &#246;&#229;&#239;&#238;&#247;&#234;&#232;
           FFirstBitsLen := FTotalBits;
         end;
     end//If FTotalBits < 8
    else//&#197;&#241;&#235;&#232; &#234;&#238;&#235;-&#226;&#238; &#225;&#232;&#242;&#238;&#226; &#225;&#238;&#235;&#252;&#248;&#229; 8


 
dmk ©   (2005-03-14 22:02) [34]

begin
       //&#229;&#241;&#235;&#232; &#237;&#224;&#247;&#224;&#235;&#252;&#237;&#251;&#233; &#225;&#232;&#242; &#237;&#229; &#237;&#243;&#235;&#229;&#226;&#238;&#233;
       If StartBit <> 0 then
         begin
           //&#209;&#247;&#232;&#242;&#224;&#229;&#236;, &#247;&#242;&#238; &#228;&#235;&#232;&#237;&#224; &#246;&#229;&#239;&#238;&#247;&#234;&#232; &#226; &#239;&#229;&#240;&#226;&#238;&#236; &#225;&#224;&#233;&#242;&#229;
           //&#240;&#224;&#226;&#237;&#224; &#238;&#241;&#242;&#224;&#226;&#248;&#232;&#236;&#241;&#255; &#225;&#232;&#242;&#224;&#236;
           FFirstBitsLen := 8 - StartBit;
           //&#207;&#238;&#241;&#236;&#238;&#242;&#240;&#232;&#236;. &#209;&#234;&#238;&#235;&#234;&#238; &#230;&#229; &#225;&#232;&#242;&#238;&#226; &#238;&#241;&#242;&#224;&#235;&#238;&#241;&#252;?
           Dec(FTotalBits,FFirstBitsLen);
           //&#197;&#241;&#235;&#232; &#238;&#241;&#242;&#224;&#235;&#238;&#241;&#252; 8 &#232;&#235;&#232; &#236;&#229;&#237;&#252;&#248;&#229; &#242;&#238;
           If FTotalBits <= 8 then
             begin
               //&#196;&#235;&#255; &#246;&#232;&#234;&#235;&#224; &#225;&#232;&#242;&#238;&#226; &#237;&#229;&#242;
               FBitsForCycle := 0;
               //&#206;&#237;&#232; &#226;&#241;&#229; &#228;&#235;&#255; &#239;&#238;&#241;&#235;&#229;&#228;&#237;&#229;&#227;&#238; &#239;&#232;&#234;&#241;&#229;&#235;&#224;
               FLastBitsLen := FTotalBits;
             end
            else//&#229;&#241;&#235;&#232; &#238;&#241;&#242;&#224;&#235;&#238;&#241;&#252; &#225;&#238;&#235;&#252;&#248;&#229; &#225;&#232;&#242;&#238;&#226;
             begin
               //&#196;&#235;&#232;&#237;&#224; &#246;&#229;&#239;&#238;&#247;&#234;&#232; &#226; &#239;&#238;&#241;&#235;&#229;&#228;&#237;&#229;&#236; &#225;&#224;&#233;&#242;&#229;
               FLastBitsLen := FTotalBits mod 8;
               //&#224; &#228;&#235;&#255; &#246;&#232;&#234;&#235;&#224; &#247;&#242;&#238;-&#242;&#238; &#232;&#236;&#229;&#229;&#236;
               FBitsForCycle := FTotalBits - FLastBitsLen;
             end;//else
         end//If aX <> 0
        else//&#197;&#241;&#235;&#232; &#226;&#241;&#229; &#230;&#229; &#239;&#232;&#234;&#241;&#229;&#235;&#251; &#237;&#224;&#247;&#232;&#237;&#224;&#254;&#242;&#241;&#255; &#241; 0-&#227;&#238; &#225;&#232;&#242;&#224;
         begin
           //&#210;&#238; &#239;&#229;&#240;&#226;&#251;&#233; &#225;&#224;&#233;&#242; &#239;&#238;&#235;&#237;&#251;&#233;
           FFirstBitsLen := 0;
           //&#202;&#238;&#235;-&#226;&#238; &#225;&#224;&#233;&#242; &#228;&#235;&#255; &#246;&#232;&#234;&#235;&#224;
           FBitsForCycle := (FTotalBits shr 3) shl 3;  
           //&#202;&#238;&#235;-&#226;&#238; &#225;&#232;&#242; &#226; &#239;&#238;&#241;&#235;&#229;&#228;&#237;&#229;&#236; &#225;&#224;&#233;&#242;&#229;
           FLastBitsLen := FTotalBits - FBitsForCycle;
         end;
     end;//If FTotalBits >= 8

   If FFirstBitsLen <> 0 then
     begin
      //&#234;&#238;&#235;-&#226;&#238; &#225;&#232;&#242;&#238;&#226; &#240;&#224;&#226;&#237;&#238; 8 - &#239;&#238;&#239;&#240;&#224;&#226;&#234;&#224; &#237;&#224; &#237;&#224;&#247;&#224;&#235;&#238; &#225;&#232;&#242;&#224;
      FBitsLen := FFirstBitsLen;

      //&#209;&#236;&#229;&#249;&#229;&#237;&#232;&#229; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; RGBBits
      asm
        mov     eax, SrcAddr
        mov     al, [eax]                 //&#215;&#232;&#242;&#224;&#229;&#236; &#239;&#232;&#234;&#241;&#229;&#235;
        and     eax, $000000FF            //&#206;&#247;&#232;&#241;&#242;&#232;&#236; &#241;&#242;&#224;&#240;&#248;&#232;&#229; 3 &#225;&#224;&#233;&#242;&#224; &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224; EAX
        and     al, gvIndexedMask         //&#206;&#242;&#234;&#235;&#254;&#247;&#229;&#237; &#235;&#232; &#234;&#224;&#237;&#224;&#235;? &#210;&#229;&#239;&#229;&#240;&#252; &#226; AL 8 &#239;&#232;&#234;&#241;&#229;&#235;&#238;&#226; &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#255;
        shl     eax, 5                    //&#211;&#236;&#237;&#238;&#230;&#224;&#229;&#236; &#237;&#224; 32, &#242;.&#234;. &#253;&#235;&#229;&#236;&#229;&#237;&#242; &#236;&#224;&#241;&#241;&#232;&#226;&#224; - &#253;&#242;&#238; 32 &#225;&#224;&#233;&#242;&#224;
        mov     BitsOffs, eax
      end;

      //&#202;&#238;&#239;&#232;&#240;&#243;&#229;&#236; RGB &#225;&#224;&#233;&#242;&#251; &#226; &#234;&#238;&#237;&#229;&#247;&#237;&#251;&#233; &#225;&#243;&#244;&#229;&#240;
      MoveBytes(RgbBits + BitsOffs + (FBitsStart shl 2), DestAddr, FBitsLen shl 2);
      //&#209;&#236;&#229;&#249;&#224;&#229;&#236;&#241;&#255; &#234; &#241;&#235;&#229;&#228;&#243;&#254;&#249;&#229;&#236;&#243; &#225;&#224;&#233;&#242;&#243; &#226; &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#232;
      Inc(SrcAddr);
      //&#209;&#236;&#229;&#249;&#224;&#229;&#236;&#241;&#255; &#234; &#241;&#235;&#229;&#228;&#243;&#254;&#249;&#232;&#236; &#225;&#232;&#242;&#224;&#236; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; RGBBits
      Inc(DestAddr,FBitsLen shl 2);
    end;


 
dmk ©   (2005-03-14 22:02) [35]

If FBitsForCycle <> 0 then
     begin
       While FBitsForCycle <> 0 do
         begin
           //&#209;&#236;&#229;&#249;&#229;&#237;&#232;&#229; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; RGBBits
           asm
             mov     eax, SrcAddr
             mov     al, [eax]                 //&#215;&#232;&#242;&#224;&#229;&#236; &#239;&#232;&#234;&#241;&#229;&#235;
             and     eax, $000000FF            //&#206;&#247;&#232;&#241;&#242;&#232;&#236; &#241;&#242;&#224;&#240;&#248;&#232;&#229; 3 &#225;&#224;&#233;&#242;&#224; &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224; EAX
             and     al, gvIndexedMask         //&#206;&#242;&#234;&#235;&#254;&#247;&#229;&#237; &#235;&#232; &#234;&#224;&#237;&#224;&#235;? &#210;&#229;&#239;&#229;&#240;&#252; &#226; AL 8 &#239;&#232;&#234;&#241;&#229;&#235;&#238;&#226; &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#255;
             shl     eax, 5                    //&#211;&#236;&#237;&#238;&#230;&#224;&#229;&#236; &#237;&#224; 32, &#242;.&#234;. &#253;&#235;&#229;&#236;&#229;&#237;&#242; &#236;&#224;&#241;&#241;&#232;&#226;&#224; - &#253;&#242;&#238; 32 &#225;&#224;&#233;&#242;&#224;
             mov     BitsOffs, eax
           end;

           MoveBytes(RgbBits + BitsOffs, DestAddr, 32);
           Inc(SrcAddr);
           Inc(DestAddr,32);
           Dec(FBitsForCycle,8);
         end;//While
     end;

   If FLastBitsLen <> 0 then
     begin
       //&#209;&#236;&#229;&#249;&#229;&#237;&#232;&#229; &#226; &#236;&#224;&#241;&#241;&#232;&#226;&#229; RGBBits
       asm
         mov     eax, SrcAddr
         mov     al, [eax]                 //&#215;&#232;&#242;&#224;&#229;&#236; &#239;&#232;&#234;&#241;&#229;&#235;
         and     eax, $000000FF            //&#206;&#247;&#232;&#241;&#242;&#232;&#236; &#241;&#242;&#224;&#240;&#248;&#232;&#229; 3 &#225;&#224;&#233;&#242;&#224; &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224; EAX
         and     al, gvIndexedMask         //&#206;&#242;&#234;&#235;&#254;&#247;&#229;&#237; &#235;&#232; &#234;&#224;&#237;&#224;&#235;? &#210;&#229;&#239;&#229;&#240;&#252; &#226; AL 8 &#239;&#232;&#234;&#241;&#229;&#235;&#238;&#226; &#232;&#231;&#238;&#225;&#240;&#224;&#230;&#229;&#237;&#232;&#255;
         shl     eax, 5                    //&#211;&#236;&#237;&#238;&#230;&#224;&#229;&#236; &#237;&#224; 32, &#242;.&#234;. &#253;&#235;&#229;&#236;&#229;&#237;&#242; &#236;&#224;&#241;&#241;&#232;&#226;&#224; - &#253;&#242;&#238; 32 &#225;&#224;&#233;&#242;&#224;
         mov     BitsOffs, eax
       end;

       MoveBytes(RgbBits + BitsOffs, DestAddr, (FLastBitsLen shl 2));
     end;//If
end;


 
Fenik   (2005-03-14 22:25) [36]

>dmk ©

Блин, ну ты даешь. Человеку нужен алгоритм, красивый четкий наглядный код. А не секреты оптимизации графики инструментами встроенного ассемблера. Учится он ещё, понимаешь? =)


 
Штотоносец   (2005-03-14 23:21) [37]

YurikGL ©   (14.03.05 21:33) [30]

Вот ты мой код даже не глянул =) я именно это и пытался реализовать. И сейчас я его доделал, и он теперь работает правильно с любым количеством цветности. Вот последний вариант:

procedure Tfrm_Main.GetGrayScale(Value:Integer);
var
 i,w,h:integer;
 a,c:Real;
 b:byte;
begin
 w:=0;
 h:=0;
 a:=255/value;
 for i:=1 to Length(ArrByteImg) do begin
   b:=ArrByteImg[i-1];
   c:=Round(b/a);
   if (b-a*c)>(a/2) then c:=Round(b/(a+1));
   b:=Round(c*a);
   Image2.Canvas.Pixels[w,h]:=b shl 16 + b shl 8 + b;
   inc(w);
   if w=Image2.Width then begin
     w:=0;
     inc(h);
   end;
 end;
end;


Остается теперь оптимизацией заняться =)


 
dmk ©   (2005-03-14 23:49) [38]

2 Fenik
Я не волшебник, я только учусъ (C) Золушка
Ну а вдруг ему интересно?! =)


 
Штотоносец   (2005-03-14 23:55) [39]


dmk ©   (14.03.05 23:49) [38]
Ну а вдруг ему интересно?! =)


Да вообщем интересно, но с такими коментариями, код сложнее воспринимается =)


 
dmk ©   (2005-03-15 00:52) [40]

Так черещз блокнот скопируй и шрифт поменяй.
Все читается =)



Страницы: 1 2 вся ветка

Текущий архив: 2005.07.11;
Скачать: CL | DM;

Наверх




Память: 0.64 MB
Время: 0.043 c
14-1118041265
Кабан
2005-06-06 11:01
2005.07.11
Цифровые фильтры


14-1118385912
syte_ser78
2005-06-10 10:45
2005.07.11
Задачка придуманая мной.


8-1110969007
Tankist
2005-03-16 13:30
2005.07.11
Как записать звук, и проиграть?


1-1119534181
DimMih
2005-06-23 17:43
2005.07.11
Подскажите пожалуйста как реализовать кратность?


9-1112675007
Xeno
2005-04-05 08:23
2005.07.11
Полноэкранный режим