По-пиксельный анализ картинки.

Тема в разделе "Delphi - Multimedia, Графика, Игры", создана пользователем xopek160183, 4 мар 2011.

  1. xopek160183

    xopek160183 Гость

    Hi всем. Появился такой вопрос: прога должная брать картинку и анализировать ее содержимое по цветам пикселей. Изначально подразумевается, что картинка серая (или в крайнем случае черно-белая). Прога должна пробегать по всем пикселям и в зависимости от их цвета оставлять соответствующие записи в лог-файле анализа картинки.
    Я на форме создал paitbox и для проверки две переменные bitmap и binmap1. В первую через диалог из файла загружаю картинку и затем через scanline пытаюсь рассмотреть содержимое. Но че-то я не догоняю. Для проверки специально создал маленький рисуночек, в котором просто вертикальная толстая черная линия в середине белого фона.
    Для проверки работы сделал следующее - после получения файла в bitmap, он анализируется и черные точки должны быть заменены например на красные. Кусок пробного кода:

    Код (Text):
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Bitmap, Bitmap1:Tbitmap;
    x,y:integer;
    p:pbytearray;
    begin
    bitmap:=tbitmap.Create;
    bitmap1:=tbitmap.Create;
    if OpenDialog1.Execute then
    bitmap.LoadFromFile(opendialog1.FileName);
    paintbox1.Canvas.Draw(0,0,Bitmap);
    for y := 0 to BitMap.Height -1 do
    begin
    P := BitMap.ScanLine[y];
    for x := 0 to BitMap.Width -1 do
    if p[x]=clblack then
    bitmap1.Canvas.Pixels[x,y]:=clred

    end;
    //bitmap1:=bitmap;
    paintbox1.Canvas.Draw(bitmap.Width+2,0,bitmap1);

    end;
    Казалось бы - банальная задача, но не получается!
    Я новичок в программировании на делфи и догнать не могу в сложившейся ситуации:
    Значения p[x] принимают какие-то неожиданные значения (255, затем 248 и еще какие-то). И соответственно и преобразование осуществляется не то, которое должно быть. Также: Если разкоментить строку bitmap1:=bitmap, то копия рисунка рисуется рядом с первой, т.е. bitmap1 получает нормальное значение. А если она закоментирована, то ничего не выводится. Хотя если в цикле в строке bitmap1.Canvas.Pixels[x,y]:=clred убрать bitmap1 и рисовать непосредственно на канве формы, то рисунок (не тот который должен быт, но) по-точечно рисуется! Ничего понять не могу! Вечер просидел, мозг вынес, но так и не смог понять, что я не так делаю!!!
    Плиз, помогите!
    PS. Может есть какие-то другие варианты (алгоритмы) выполнения поставленной задачи?
     
  2. xopek160183

    xopek160183 Гость

    Что??!!! Никто помочь не может?????!!! :welcome:
    Я вчера немного переделал - прописал в битмапе монохромную палитру и pixelformat:=pf1bit
    Сделал малюсенькую картинку 4х4 пикселя и закрасил в черный цвет две средние вертикальные полосы. (файл bmp).
    Но чего то я догнать не могу, значения p[x] принимают следующие значения
    x 0 1 2 3 4
    y
    0 144 0 0 0 0
    1 144 0 0 0 0
    2 144 0 0 0 144
    3 144 0 0 0 144

    Понятно, что при x=4 значения р[x] нам не нужны, но тем не менее!
    Народ, объясните, плз, что это за фигня? Как определить цвет конкретной точки?
     
  3. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Дело в том что если делать через P := BitMap.ScanLine[y]; то оно просто так(в чистом виде(p[x]=clblack) немного кривовато(там возвращаемый масив напрямую зависть от pixelformat)).
    Лучше сделать через обычный канвас(дольше,но проверять на привальность легче, а когда всё правильно будет работать то можно сделать и через ScanLine):
    Код (Delphi):
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Bitmap, Bitmap1:Tbitmap;
    x,y:integer;

    begin
    if OpenDialog1.Execute then
    begin
    bitmap:=tbitmap.Create;
    bitmap1:=tbitmap.Create;
    bitmap.LoadFromFile(opendialog1.FileName);
    bitmap1.width:=bitmap.width;
    bitmap1.Height:=bitmap.Height;
    paintbox1.Canvas.Draw(0,0,Bitmap);
    for y := 0 to BitMap.Height -1 do
    for x := 0 to BitMap.Width -1 do
    if BitMap.canvas.Pixels[x,y]=clblack then
    bitmap1.Canvas.Pixels[x,y]:=clred else bitmap1.Canvas.Pixels[x,y]:=clwhite;

    end;
    paintbox1.Canvas.Draw(bitmap.Width+2,0,bitmap1);
    bitmap.free;
    bitmap1.free;
    end;

    end;
     
  4. xopek160183

    xopek160183 Гость

    Спасибо! Попробую
     
  5. xopek160183

    xopek160183 Гость

    Спасибо! Попробую!
    Да! Все гуд! Так пошло! Следом еще вопрос! Если картинка будет не черно-белая, а серая - как будут делиться серые оттенки? Т.е какие значения будет принимать pixels[x,y] ? Мне большая глубина цвета не нужна. Максимум несколько оттенков - пока 2-4. (объясню зачем - делаю обработку графики для рассчета программы для ЧПУ гравировки на основе растрового рисунка. В зависимости от оттенка будет та или иная глубина фрезерования)
     
  6. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    pixels[x,y] возвращает цвет в виде TColor,а не r g b по отдельности.
    Код (Delphi):
    var r,g,b:byte;
    begin
    r:=getRvalue(image1.canvas.pixels[x,y]);// значение красного
    g:=getGvalue(image1.canvas.pixels[x,y]);// зелёного
    b:=getBvalue(image1.canvas.pixels[x,y]);// синего
    end;
    r,g,b примерно равные
     
  7. aZa9A

    aZa9A Гость

    Спасибо было позновательно
     
Загрузка...

Поделиться этой страницей