Страница 1 из 1

Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 05 фев 2013, 14:30
Monah_Monahich
Задача составная, так что буду рад решению одной из частей.

Программа делает некоторые вычисления и показывает результаты на экране. Хочу иметь возможность сохранить результаты в файл в виде изображения. Это изображение будет использовано в GUI как кнопка. Если рассматривать игры, то в DOOM 3 такая штука с сохранениями была. нажал "загрузить" и видишь экран при сохранении.

Предполагаю такие задачи:
1) Переключение на камеру с которой делается картинка.
2) Сохранение снимка.
3) Загрузка изображения в элемент GUI.
4) Управление тем. что попадет в кадр при снимке.

Готов к обсуждению и переписке.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 05 фев 2013, 14:39
cibersant
http://2lx.ru/2009/08/sozdanie-snimka-ekrana-v-c/ это просто снимок экрана на C#.А в твоём случае наверное нужно копать в сторону буфера обмена.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 05 фев 2013, 15:14
Monah_Monahich
cibersant писал(а):http://2lx.ru/2009/08/sozdanie-snimka-ekrana-v-c/ это просто снимок экрана на C#.

Не понимает, что такое Bitmap. наверное надо что-то подключить.

cibersant писал(а):А в твоём случае наверное нужно копать в сторону буфера обмена.

Нет. Изображения нужны на ПК как файлы.


Снимок экрана. Простое решение.
Синтаксис:
Используется csharp
void OnGUI()   {
    if (GUI.Button(new Rect(20, 20, 150, 100), "CaptureScreenshot"))
    { Application.CaptureScreenshot("Screenshot.png"); }
}
 



Теперь, хорошо бы научится снимать конкретной камерой. Загружать и отображать изображение в ГУИ.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 05 фев 2013, 17:01
cibersant
Так камера конкретная изображение хранит в буфере.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 06 фев 2013, 23:04
Monah_Monahich
Есть такое решение. (На сцене 2 камеры, "Camera1" та, с которой смотрят)
Синтаксис:
Используется csharp
        void OnGUI()
        {
            if (GUI.Button(new Rect(20, 20, 150, 100), "CaptureScreenshot"))
            {
                       
                        RenderTexture renderTexture = RenderTexture.GetTemporary(500, 500, 24);
                RenderTexture.active = renderTexture;
                       
                        Camera tCamera = GameObject.Find ("Camera2").camera;
                       
                tCamera.targetTexture = renderTexture;
                tCamera.Render();
                       
                Texture2D screenShot = new Texture2D(400, 400);
                        screenShot.ReadPixels(new Rect(0,0,400,400),0,0);
                        screenShot.Apply();
                       
                        byte[] bytes = screenShot.EncodeToPNG();
                        string filename = "screenShot111.png";
                        System.IO.File.WriteAllBytes(filename, bytes);
                }      
        }
 

Выдает ошибку, но работает.

ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.
UnityEngine.Texture2D:ReadPixels(Rect, Int32, Int32)
CameraScreenShot:OnGUI() (at Assets/tempScriptObject/CameraScreenShot.cs:30)


Помогите с ошибкой.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 06 фев 2013, 23:20
cibersant
Monah_Monahich писал(а):
cibersant писал(а):Так камера конкретная изображение хранит в буфере.

Очень хорошо. Как к этому буферу добраться ? Мне нужно делать снимки, скрытой камерой, пока юзер смотрит на сцену главной камерой.

Нужно директх колупать наверное.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 06 фев 2013, 23:42
Neodrop
Camera.Render в назначенную RenderTexture

Берём полученную текстуру и делаем с ней что заблагорассудится. (popcorn)

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 07 фев 2013, 00:40
Monah_Monahich
Neodrop писал(а):Берём полученную текстуру и делаем с ней что заблагорассудится.


На одно сообщение выше есть код и описание ошибки. Не подскажешь в чем проблема ? Неужели, прямоугольник отдельной переменной делать надо ? :)
Спасибо.

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 07 фев 2013, 00:43
cibersant
Neodrop писал(а):Camera.Render в назначенную RenderTexture

Берём полученную текстуру и делаем с ней что заблагорассудится. (popcorn)

Точно я об этом не догадался .

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 07 фев 2013, 07:09
seaman
На одно сообщение выше есть код и описание ошибки. Не подскажешь в чем проблема ?

Проблема в том, что Вы пытаетесь получить кадр с камеры до окончания отрисовки кадра. Одно решение Вам привели выше - camera.Render(). Можно решить по другому - положить код получения текстуры в OnPostRender(). Или в корутину и в начале корутины WaitForEndOfFrame();

Re: Сделать снимок сцены камерой и показать его в программе.

СообщениеДобавлено: 07 фев 2013, 10:35
Monah_Monahich
seaman писал(а):Можно решить по другому - положить код получения текстуры в OnPostRender(). Или в корутину и в начале корутины WaitForEndOfFrame();


Спасибо. Понял. Работает.
Синтаксис:
Используется csharp
void OnGUI()
{
    if (GUI.Button(new Rect(20, 20, 150, 100), "CameraScreenshot"))
    {
        startRender = true;
    }
}

bool startRender = false;

void OnPostRender() {
    if(startRender) {
               
        RenderTexture renderTexture = RenderTexture.GetTemporary(500, 500, 24);
        RenderTexture.active = renderTexture;
               
        Camera tCamera = GameObject.Find ("Camera2").camera;
               
        tCamera.targetTexture = renderTexture;
        tCamera.Render();
               
        Texture2D screenShot = new Texture2D(400, 400);
        screenShot.ReadPixels(new Rect(0,0,400,400),0,0);
        screenShot.Apply();
               
        byte[] bytes = screenShot.EncodeToPNG();
        string filename = "screenShot111.png";
        System.IO.File.WriteAllBytes(filename, bytes);
               
        startRender = false;
    }
}
 

Я кодом не спамлю я его тут сохраняю. :)