2010-03-28 4 views
1

Я хочу масштабировать изображение с помощью openGL, может ли кто-нибудь предоставить мне такой код о том, как это сделать?
PS, я использую JGL в качестве библиотеки openGL для Java.Как масштабировать изображение с помощью openGL (JGL)?

+0

Развернуть «масштаб изображения». – genpfault

+0

Не могли бы вы объяснить это больше? –

+1

Я (и, возможно, другие) понятия не имею, что вы имеете в виду, когда говорите, что хотите «масштабировать изображение».Я думаю, вы можете сделать текстурированный квадрат с преобразованием шкалы в FBO, а затем прочитать фреймбуфер, но я понятия не имею. – genpfault

ответ

1

Я расскажу об этом, так как вы можете найти учебники для почти каждой части решения.

Вам необходимо загрузить изображение с диска и создать текстуру.

Вам необходимо создать объект фреймбуфера (FBO) с требуемыми размерами цели (в вашем случае двойная ширина, двойная высота). Сделайте FBO активным для рендеринга.

Извлечь полноэкранный четырехъядерный квадрат с нанесенной текстурой.

Прочтите результат, используя glReadPixels().

И это все ... оборудование для текстурирования позаботится о его масштабировании. Но это, скорее всего, будет медленнее, чем если бы это было сделано на процессоре, особенно для «масштабирования 2x».

EDIT: по просьбе ОП необходимо включить исходный код.

Так ... для загрузки изображения в Java, вы бы пойти на это:

BufferedImage img; 
try { 
    img = ImageIO.read(new File("myLargeImage.jpg")); 
} catch (IOException e) { /* ... */ } 
int w = img.getWidth(), h = img.getHeight(); 

Для JGL, один, возможно, захотите преобразовать изображение в массив:

byte [][][] imageData = new byte[img.getWidth()][img.getHeight()][3]; // alloc buffer for RGB data 
for(int y = 0; y < h; ++ y) { 
    for(int x = 0; x < w; ++ x) { 
     int RGBA = img.getRGB(x, y); 
     imageData[x][y][0] = RGBA & 0xff; 
     imageData[x][y][1] = (RGBA >> 8) & 0xff; 
     imageData[x][y][2] = (RGBA >> 16) & 0xff; 
    } 
} 

Примечание что может быть и альфа-канал (для прозрачности), и это, вероятно, будет довольно медленным. Также можно использовать:

int[] rgbaData = img.GetRGB(0, 0, w, h, new int[w * h], 0, w); 

Но это не возвращает данные в правильном формате, ожидаемом JGL. Везет, как утопленнику. Затем вам нужно заполнить текстуру:

int[] texId = {0}; 
gl.glGenTextures(1, texId); // generate texture id for your texture (can skip this line) 
gl.glEnable(GL.GL_TEXTURE_2D); 
gl.glBindTexture(GL.GL_TEXTURE_2D, texId[0]); // bind the texture 
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); // set alignment of data in memory (a good thing to do before glTexImage) 
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP); 
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP); // set clamp (GL_CLAMP_TO_EDGE would be better) 
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); 
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); // set linear filtering (so you can scale your image) 
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, w, h, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, imageData); // upload image data to the texture 

После того, как у вас есть текстуры, вы можете рисовать вещи. Давайте ресэмплировать изображение:

int newW = ..., newH = ...; // fill-in your values 
gl.glViewport(0, 0, newW, newH); // set viewport 

gl.glMatrixMode(GL.GL_MODELVIEW); 
gl.glLoadIdentity(); 
gl.glMatrixMode(GL.GL_PROJECTION); 
gl.glLoadIdentity(); 
gl.glColor3f(1.0f, 1.0f, 1.0f); // set "white" color 
gl.glDisable(GL.GL_CULL_FACE); // disable backface culling 
gl.glDisable(GL.GL_LIGHTING); // disable lighting 
gl.glDisable(GL.GL_DEPTH_TEST); // disable depth test 
// setup OpenGL so that it renders texture colors without modification (some of that is not required by default) 

gl.glBegin(GL_QUADS); 
gl.glTexCoord2f(0.0f, 1.0f); 
gl.glVertex2f(-1.0f, -1.0f); 
gl.glTexCoord2f(1.0f, 1.0f); 
gl.glVertex2f(+1.0f, -1.0f); 
gl.glTexCoord2f(1.0f, 0.0f); 
gl.glVertex2f(+1.0f, +1.0f); 
gl.glTexCoord2f(0.0f, 0.0f); 
gl.glVertex2f(-1.0f, +1.0f); 
gl.glEnd(); 
// draw a fullscreen quad with your texture on it (scaling is performed here) 

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

byte[][][] newImageData = new byte[newW][newH][3]; 
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); // set alignment of data in memory (this time pack alignment; a good thing to do before glReadPixels) 
gl.glReadPixels(0, 0, newW, newH, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, newImageData); 

И тогда данные могут быть преобразованы в BufferedImage аналогичным образом входное изображение IMG был преобразован в ImageData.

Обратите внимание, что я использовал переменную gl, то есть экземпляр класса GL. Поместите код в некоторый пример JGL, и он должен работать.

Одно слово предостережения. JGL, похоже, не поддерживает объекты фреймбуфера, так что вы ограничены размером выходного изображения по размеру окна OpenGL (попытка создания больших изображений приведет к черным границам). Его можно решить, используя многопроходный рендеринг (визуализируйте фрагмент изображения на плитке и соберите полное изображение в памяти).

Смежные вопросы