2013-03-27 1 views
0

Я пытаюсь прочитать непосредственно из буфера кадра через glReadPixels(), чтобы я мог сделать снимок экрана из того, что на моем экране.
Я не использую графический интерфейс, вместо этого он должен печатать исходное содержимое экрана всякий раз, когда я касаюсь экрана (этого достаточно для начала).Поиск подходящего контекста для скриншота с glReadPixels()

Я теперь застрял в получении правильного контекста для моей функции gl.glReadPixels().
Потому что я думаю, что контекст, который я получаю в данный момент, не имеет никакого отношения к тому, что на самом деле находится на экране.

При запуске приложения он выводит сообщение об ошибке libEGL, который говорит

вызова OpenGL ES API без какого-либо текущего контекста (один раз за один нити)

и после этого я получаю свой массив заполненный нулями.

Чтобы скрыть мое приложение, я использую следующую строку в своем манифесте.

android:theme="@android:style/Theme.Translucent.NoTitleBar" 

А вот код:

public class ScreenshotActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_UP) { 
       savePixels(); 
     } 
     return true; 
    } 


    EGL10 egl = (EGL10) EGLContext.getEGL(); 
    GL10 gl = (GL10) egl.eglGetCurrentContext().getGL(); 

    public void savePixels() { 
     w= getWidth(this); 
     h= getHeight(this); 
     int b[] = new int[w * h]; 
     int bt[] = new int[w * h]; 
     IntBuffer ib = IntBuffer.wrap(b); 
     ib.position(0); 

     gl.glReadPixels(0, 0, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib); 


     for (int i = 0; i < h; i++) { 
      for (int j = 0; j < w; j++) { 
       int pix = b[i * w + j]; 
       int pb = (pix >> 16) & 0xff; 
       int pr = (pix << 16) & 0x00ff0000; 
       int pix1 = (pix & 0xff00ff00) | pr | pb; 
       bt[(h - i - 1) * w + j] = pix1; 
       } 
      } 

      Log.w("debug", Arrays.toString(bt)); 
      moveTaskToBack(true); 
    } 
} 

Помощь высоко ценится :)

ответ

0

Наконец-то найдена программа с открытым исходным кодом, которая не использует/dev/graphics/fb0 для захвата фреймбуфера.

В комплект пакета fb2png входит программа C и скрипт python, которые работают отлично.

0
mGLSurfaceView.queueEvent(new Runnable() { 
    public void run() { 
    savePixels(); 
    } 
}); 

вы должны изменить mGLSurfaceView к вашему SurfaceView Instance.

+0

Но что такое мой SurfaceView, когда я его не создам? Мое приложение скрыто и должно захватывать содержимое экрана (который не принадлежит моему приложению). – user2207148

1

Могли люди перестать пытаться злоупотреблять OpenGL для принятия скриншотов? Это нормально, если вы хотите захватить вывод рендеринга программы, которая вызывала вызов glReadPixels, но как только другие программы являются источником предполагаемых пикселей, он становится крайне ненадежным.

Единственный надежный способ получить скриншоты с полным экраном - это прямое считывание с видеообъектива графического процессора. Android основан на Linux и Linux предлагает для этого устройство fbdev. Поскольку работа со всеми этими ioctls немного громоздка, следует использовать некоторую тестируемую библиотеку. Там есть библиотека для Android, которая предлагает специальный API для снятия скриншотов: http://code.google.com/p/android-screenshot-library/wiki/DeveloperGuide

+0

Сначала это выглядело многообещающим, но есть проблема. По крайней мере, когда я запускаю asl-demo.apk, он просто считывает то, что находится в/dev/graphics/fb0, которое на моем устройстве только черное. Я читал, что это как-то связано с чипом tegra 3, который не использует фреймбуфер fb0. Уверен, что я заполнил fb0 с помощью/dev/urandom и впоследствии получил это случайное изображение шума в качестве скриншота. Значит, похоже, что он не читал непосредственно с видеообуфера GPU, не так ли? – user2207148

+0

Вы знаете, как работает screencap.cpp? Потому что эта функция способна снимать скриншоты. Мне просто нужно знать, где он получает данные для скриншота. https: // GitHub.com/android/platform_frameworks_base/blob/master/cmds/screencap/screencap.cpp – user2207148

+1

@ user2207148: Это говорит с компоновщиком отображения для получения композитного изображения. Помимо чтения непосредственно из памяти фреймбуфера, это единственный надежный способ захвата скриншота в композитных графических системах. – datenwolf