LoadBMP или "Как работать с картинкой?"

Предыдущая тема Следующая тема Перейти вниз

LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Сб Июн 06, 2009 9:03 pm

Мне интересно узнать, как прямо в памяти изменять загруженную BMP картинку. Как её можно создать (определённого размера) и как изменить конкретные пикселя? (То есть пиксель 24,25 должен быть цвета FF089B)

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  tux в Вс Июн 07, 2009 7:51 am

а шочнтся самому, или пойдет библиотека?
Если библиотектой, то оч онравилась GD, простенькая, и все преобразования мона делать прям в памяти, без отрисовки, в екзамплах помоему она была...
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Вс Июн 07, 2009 12:25 pm

У меня есть десяток текстур в формате "BITMAP_RGBImageRec Ptr" Мне надо рисовать в одну текстуру значение освещённости, а потом накладывать её вместе с одной из дести и за счёт этого получать попиксельное освещение и тени. Мне нужно знать как прямо в текстуре изменять цвет каждого пикселя. Мне надо работать именно с BITMAP_RGBImageRec Ptr.

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Замабувараев в Вс Июн 07, 2009 1:57 pm

Во-первых, для начала нужно создать картинку функцией ImageCreate

image_buffer = ImageCreate(Width, Height, [Color])

где Width и Height - это ширина и высота картинки, Color - это цвет картинки по умолчанию. Функция возвращает указатель на картинку, с помощью которого можно манипулировать изображением. Если возвращается 0, то произошла ошибка. Если изображение больше не нужно, необходимо освободить память функцией ImageDestroy, например так:

Код:


Dim image_buffer As Any Ptr

' Устанавливаем разрешение экрана
ScreenRes 800, 600, 32

' Создаём изображение с тёмно-зелёным фоном
image_buffer = ImageCreate(64, 64, RGB(0, 128, 0))

' Рисуем полупрозрачную красную окружность на картинке
Circle image_buffer, (32, 32), 28, RGBA(255, 0, 0, 128), , , 1.0, F

' Рисуем картинку на экране методом PSet (точное соответствие)
Put (120, 60), image_buffer, PSet
' Рисуем картинку на экране в другой точке методом Alpha (с прозрачностью)
Put (140, 80), image_buffer, Alpha

Sleep

' Освобождаем память
ImageDestroy image_buffer

Далее на этом изображении можно рисовать точки, прямые, окружности и т.д.

Для того чтобы загрузить картинку с жёсткого диска, есть функция BLoad, возвращающая ненулевое значение в случае ошибки:

result = BLoad(FileName [, dest])

где FileName - это имя файла в формате BMP (никаких файлов со сжатием, таких как JPG, GIF, PNG и т.д.), dest - это буфер изображения, созданного функцией ImageCreate. Если dest отсутствует, картинка загружается прямо на экран. Надо сказать что BLoad загружает полноцветные изображения (15-, 16-, 24- или 32 бит на пиксель) или с палитрой (8 бит на пиксель или меньше). Загружает также информацию об альфа-канале, если таковой доступен.
Пример:

Код:


' Загружаем 48x48 bitmap в буфер
Screen 18, 32
Dim myImage As Any Ptr = ImageCreate(48, 48)
BLoad "picture.bmp", myImage
Put (10,10), myImage
ImageDestroy( myImage )
Sleep
avatar
Замабувараев

Сообщения : 99
Дата регистрации : 2008-08-20
Возраст : 34
Откуда : Красноярск

Посмотреть профиль http://www.freebasic.su

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Вс Июн 07, 2009 8:48 pm

Понятно. У меня кое-что другое:
Код:

Dim As BITMAP_RGBImageRec Ptr Sky(1 To 2)
Sky(1)=LoadBMP(exepath + "/Textures/skybox/5_2.bmp")
Как с этим работать? (Я имею ввиду менять изображение, т.к. размеры и buffer можно узнать самому Sky(1)->sizeX, Sky(1)->sizeY, Sky(1)->buffer)

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Вт Июн 09, 2009 4:19 pm

Помогите разобраться с этой функцией - я не понимаю где именно в памяти храниться текстура.
Код:

const BITMAP_ID = &H4D42

type BITMAPINFOHEADER Field = 1
  biSize          as integer
  biWidth        as integer
  biHeight        as integer
  biPlanes        as short
  biBitCount      as short
  biCompression  as integer
  biSizeImage    as integer
  biXPelsPerMeter as integer
  biYPelsPerMeter as integer
  biClrUsed      as integer
  biClrImportant  as integer
end type

type PALETTEENTRY Field = 1
  peRed  as byte
  peGreen as byte
  peBlue  as byte
  peFlags as byte
end type

type BITMAPFILEHEADER FIELD = 1
  bfType as short
  bfSize as integer
  bfReserved1 as short
  bfReserved2 as short
  bfOffBits as integer
end type

'This is a replacement for AUX_RGBImageRec because GLAUX lib is not part of
'the freebasic install (perhaps not worth having for only one useful function).
type BITMAP_RGBImageRec FIELD = 1
  sizeX as integer
  sizeY as integer
  buffer as ubyte ptr
end type


declare function LoadBMP(byref Filename as string) as BITMAP_RGBImageRec ptr

'' Loads A Bitmap Image. Only uncompressed 8 or 24 bit BITMAP immages supported
private function LoadBMP(byref Filename as string) as BITMAP_RGBImageRec ptr
  dim bitmapfileheader as BITMAPFILEHEADER '' this contains the bitmapfile header
  dim bitmapinfoheader as BITMAPINFOHEADER '' this is all the info including the palette
  dim bmpalette(256) as PALETTEENTRY      '' we will store the palette here

  dim index as integer
  dim noofpixels as integer
  dim p as ubyte ptr
  dim r as ubyte, g as ubyte, b as ubyte
  dim pbmpdata as BITMAP_RGBImageRec ptr
  dim f as integer
  f = freefile
 
  if (open (Filename, for binary, as #f) = 0) then            '' Does The File Exist?
 
    get #f, , bitmapfileheader
    if bitmapfileheader.bfType <> BITMAP_ID then
      close #f
      return 0
    end if

    get #f, , bitmapinfoheader

    if bitmapinfoheader.biBitCount=8 or bitmapinfoheader.biBitCount=24 then

      if bitmapinfoheader.biBitCount = 8 then
        for index = 0 to 255
          get #f, , bmpalette(index)
        next
      end if

      noofpixels = bitmapinfoheader.biWidth*bitmapinfoheader.biHeight

      '' allocate the memory for the image (24 bit memory image)
      pbmpdata = allocate(len(BITMAP_RGBImageRec))
      if pbmpdata = 0 then
        '' close the file
        close #f
        return 0
      end if
      pbmpdata->sizeX  = bitmapinfoheader.biWidth
      pbmpdata->sizeY  = bitmapinfoheader.biHeight
      pbmpdata->buffer = allocate(noofpixels*3)
      if pbmpdata->buffer = 0 then
        '' close the file
        close #f
        deallocate (pbmpdata)
        return 0
      end if

      '' now read it in
      p = pbmpdata->buffer
      if bitmapinfoheader.biBitCount=24 then
        for index = 0 to noofpixels -1
          '' Change from BGR to RGB format
          get #f, , b
          get #f, , g
          get #f, , r
          *p = r : p += 1
          *p = g : p += 1
          *p = b : p += 1
        next
      else
        for index = 0 to noofpixels -1
          '' Change from BGR to RGB format while converting to 24 bit
          get #f, , b
          *p = bmpalette(b).peBlue  : p += 1
          *p = bmpalette(b).peGreen : p += 1
          *p = bmpalette(b).peRed  : p += 1
        next
      end if
    else
      close #f
      return 0
    end if
    '' Success!
    close #f
    return pbmpdata
  end if

  return 0                      '' If Load Failed Return FALSE (NULL)
end function

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  tux в Вт Июн 09, 2009 8:55 pm

Код:
type BITMAP_RGBImageRec FIELD = 1
  sizeX as integer
  sizeY as integer
  buffer as ubyte ptr
end type
где buffer - указатель на область памяти, где и хранится образ картинки (один байт - один компонент цвета), в чем проблема то, в коде достаточно все прозразчно
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Вс Июн 14, 2009 2:26 pm

Спасибо, вы мне очень помогли

Код:
addr=Sky(1)->buffer+(256*x+y)*3
Poke addr, R
Poke addr+1, G
Poke addr+2, B

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Диб-секции

Сообщение  vbman в Пн Июн 15, 2009 4:36 pm

Диб-секция выдаст указатель на память, в которой хранятся данные растра в виде идущих друг за другом структур Very Happy :

Код:
Type TRGB
    rgbBlue as ubyte
    rgbGreen as ubyte
    rgbRed as ubyte
End Type

Это если картинка 24-битная Laughing . Если же 32-битная, то в начале структуры добавляется поле rgbAlpha What a Face .

Но работать надо на АПИ - загружать еще полбеды, а дальше - на чистом АПИ pig ... Хотя можно укзатель на память привести к любому указательному типу... affraid
avatar
vbman

Сообщения : 52
Дата регистрации : 2008-11-19
Возраст : 36
Откуда : Украина, Кировоград

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Gena в Пт Июн 19, 2009 1:30 pm

Диб-секция выдаст указатель на память, в которой хранятся данные растра в виде идущих друг за другом структур.
Что такое диб-секция?
Это если картинка 24-битная. Если же 32-битная, то в начале структуры добавляется поле rgbAlpha.
Это всё понятно.

Почему АПИ? всё путём - для тени мне достаточно poke addr, ub

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 24
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: LoadBMP или "Как работать с картинкой?"

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения