Поиск подходящего контекста для создания снимка экрана с помощью glReadPixels()
Я пытаюсь читать непосредственно из буфера кадра через glReadPixels(), чтобы я мог сделать снимок экрана с того, что на моем экране.
Я не использую графический интерфейс, вместо этого он должен печатать необработанное содержимое экрана всякий раз, когда я касаюсь экрана (этого достаточно для начала).
Теперь я застрял в получении правильного контекста для моей функции gl.glReadPixels().
Потому что я думаю, что контекст, который я получаю сейчас, не имеет ничего общего с тем, что на самом деле на экране.
Когда я запускаю приложение, оно печатает ошибку libEGL, которая говорит
вызов API OpenGL ES без текущего контекста (регистрируется один раз для потока)
и после этого я получаю свой массив заполнен нулями.
Чтобы скрыть свое приложение, я использую следующую строку в моем манифесте.
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);
}
}
Помощь высоко ценится:)
3 ответа
Наконец нашел программу с открытым исходным кодом, которая не использует /dev/graphics/fb0 для захвата кадрового буфера.
Пакет fb2png включает в себя программу на C и скрипт на python, которые отлично работают.
Могут ли люди перестать пытаться злоупотреблять OpenGL за создание скриншотов? Хорошо, если вы хотите захватить результаты рендеринга программы, которая вызывала glReadPixels, но как только другие программы становятся источником пикселей, это становится крайне ненадежным.
Единственный надежный способ сделать полноэкранные снимки экрана - это напрямую считывать данные из памяти видеобуфера графических процессоров. Android основан на Linux, и Linux предлагает для этого устройство fbdev. Поскольку работа со всеми этими ioctl немного трудоемка, следует использовать проверенную библиотеку. Существует библиотека для Android, которая предлагает специальный API для создания снимков экрана: http://code.google.com/p/android-screenshot-library/wiki/DeveloperGuide
mGLSurfaceView.queueEvent(new Runnable() {
public void run() {
savePixels();
}
});
Вы должны изменить mGLSurfaceView на свой экземпляр SurfaceView.