Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Max_92
25 / 7 / 2
Регистрация: 26.04.2010
Сообщений: 205
#1

Как достичь приемлемого качества фото и видео, используя CameraAPI - Программирование Android

05.12.2014, 13:41. Просмотров 361. Ответов 0
Метки нет (Все метки)

Вот уже несколько месяцев как разрабатываю библиотеку для работы с камерой, используя средства, имеющиеся в SDK (19-ом). Суть в том, что реально устройство, например, может писать видео с разрешением 720x480 (так пишет стандратная камера с высокими настройками кач-ва) и с достаточно высоким битрейтом, в то время как в моём коде, используя стандартный гугловский MediaRecorder (http://developer.android.com/referen...aRecorder.html) я такого качества добиться не могу.

Во-первых: для открытой фронтальной камеры список
Java
1
camera.getParameters().getSupportedVideoSizes();
не содержит того самого макс. разрешения,
во-вторых перед prepare() рекордера я пытаюсь выставить профиль 480P, предварительно проверив, что для камеры с таким id он действительно поддерживается:

Java
1
2
3
4
5
6
7
        if (videoSettings.quality != QUALITY.DEFAULT) {
            if (!CamcorderProfile.hasProfile(cameraId, videoSettings.quality.getValue())) {
                logger.error("profile " + videoSettings.quality.getValue() + " is not suppoted for camera with id " + cameraId
                        + ", changing to DEFAULT...");
                videoSettings.quality = QUALITY.DEFAULT;
            }
        }
после чего либо выставляю этот профиль, ловя RuntimeException, либо выставляю отдельные параметры, при том в нужном порядке (set sources -> setOutputFormat -> setVideoSize -> setVideoFrameRate -> set encoders):

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
                    if (videoSettings.quality != QUALITY.DEFAULT) {
 
            logger.debug("setting profile " + videoSettings.quality.getValue() + "...");
            try {
 
                mediaRecorder.setProfile(CamcorderProfile.get(videoSettings.quality.getValue(), cameraId));
            } catch (RuntimeException e) {
                logger.error("a RuntimeException occured during setProfile() : " + e.getMessage());
 
                videoSettings.quality = QUALITY.DEFAULT;
 
                return false;
            }
 
            logger.debug("quality=" + videoSettings.quality);
 
        } else {
 
            logger.debug("setting single parameters...");
 
            setOutputFormatByEncoder(videoSettings.videoEncoder);
            logger.debug("videoEncoder=" + videoSettings.videoEncoder);
 
            if (videoSettings.width > 0 && videoSettings.height > 0) {
                mediaRecorder.setVideoSize(videoSettings.width, videoSettings.height);
                logger.debug("videoSize: width=" + videoSettings.width + ", height=" + videoSettings.height);
            } else {
                logger.error("wrong video size: " + videoSettings.width + " x " + videoSettings.height);
            }
 
            // if bitrate value is more than max acceptable bitrate, bitrate in video file will be max and constant
            // mediaRecorder.setVideoEncodingBitRate(256000);
 
            if (videoSettings.frameRate > 0 && videoSettings.frameRate <= VideoSettings.FRAME_RATE_MAX) {
                mediaRecorder.setVideoFrameRate(videoSettings.frameRate);
                logger.debug("frameRate=" + videoSettings.frameRate);
            }
 
            mediaRecorder.setAudioEncoder(videoSettings.audioEncoder.getValue());
            logger.debug("audioEncoder=" + videoSettings.audioEncoder);
 
            mediaRecorder.setVideoEncoder(videoSettings.videoEncoder.getValue());
            logger.debug("videoEncoder=" + videoSettings.videoEncoder);
        }
смысл в том, что на выставлении профиля 480P этот exception бросается всегда, а если брать профиль HIGH, который по заверениям должен быть на всех девайсах, то разрешение выставляется самое низкое для этого телефона (176x144) и все настройки дефолтные.
вручную я параметры выставляю, если был выбран профиль DEFAULT. битрейт видео, к слову, так же нельзя выставить выше 256 kbit/s
таким образом, макс. разрешение видео у меня 480x320 и битрейт 256.

Качество фоток так же посредственное, но там ситуация несколько лучше, по крайней мере в колбеке onPictureTaken() я могу получить фотку с разрешением порядка 1600 пикселей.

Текущие параметры камеры непосредственно перед взятием фотки, например, выставляю таким образом:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    public boolean setCameraPhotoParams(PhotoSettings photoSettings) {
        logger.debug("setCameraPhotoParams()");
 
        if (camera == null) {
            logger.error("camera is null");
            return false;
        }
 
        if (photoSettings == null) {
            logger.error("photoSettings is null");
            return false;
        }
 
        if (isMediaRecorderRecording) {
            logger.error("can't set parameters: media recorder is now recording");
            return false;
        }
 
        final Parameters params;
        try {
            params = camera.getParameters();
        } catch (RuntimeException e) {
            logger.error("a RuntimeException occured during getParameters(): " + e.getMessage());
            return false;
        }
 
        boolean isPreviewSizeSupported = false;
 
        final List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();
 
        if ((photoSettings.previewWidth > 0) && (photoSettings.previewHeight > 0)) {
 
            if (supportedPreviewSizes != null && supportedPreviewSizes.size() != 0) {
                for (int i = 0; i < supportedPreviewSizes.size(); i++) {
 
                    // logger.debug(" _ preview " + supportedPreviewSizes.get(i).width + " and height " +
                    // supportedPreviewSizes.get(i).height);
 
                    if ((supportedPreviewSizes.get(i).width == photoSettings.previewWidth)
                            && (supportedPreviewSizes.get(i).height == photoSettings.previewHeight)) {
                        logger.debug("PREVIEW width " + photoSettings.previewWidth + " and height " + photoSettings.previewHeight
                                + " is supported");
                        params.setPreviewSize(photoSettings.previewWidth, photoSettings.previewHeight);
                        isPreviewSizeSupported = true;
                        break;
                    }
                }
            } else {
                logger.error("no supported preview sizes for this camera");
            }
        }
 
        if (!isPreviewSizeSupported) {
            logger.error("PREVIEW width " + photoSettings.previewWidth + " and height " + photoSettings.previewHeight + " is NOT supported");
 
            final Camera.Size optimalPreviewSize = getOptimalPreviewSize(getSupportedPictureSizes(), surfaceWidth, surfaceHeight);
            // final Camera.Size highPreviewSize = findHighSize(getSupportedPreviewSizes());
 
            photoSettings.previewWidth = optimalPreviewSize.width;
            photoSettings.previewHeight = optimalPreviewSize.height;
            params.setPreviewSize(photoSettings.previewWidth, photoSettings.previewHeight);
        }
 
        boolean isPictureSizeSupported = false;
 
        final List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes();
 
        if ((photoSettings.pictureWidth > 0) && (photoSettings.pictureHeight > 0)) {
 
            if (supportedPictureSizes != null && supportedPictureSizes.size() != 0) {
                for (int i = 0; i < supportedPictureSizes.size(); i++) {
 
                    // logger.debug(" _ preview " + supportedPictureSizes.get(i).width + " and height " +
                    // supportedPictureSizes.get(i).height);
 
                    if ((supportedPictureSizes.get(i).width == photoSettings.pictureWidth)
                            && (supportedPictureSizes.get(i).height == photoSettings.pictureHeight)) {
                        logger.debug("PICTURE width " + photoSettings.pictureWidth + " and height " + photoSettings.pictureHeight
                                + " is supported");
                        params.setPictureSize(photoSettings.pictureWidth, photoSettings.pictureHeight);
                        isPictureSizeSupported = true;
                        break;
                    }
                }
            } else {
                logger.error("no supported pictures sizes for this camera");
            }
        }
 
        if (!isPictureSizeSupported) {
            logger.error("PICTURE width " + photoSettings.pictureWidth + " and height " + photoSettings.pictureHeight + " is NOT supported");
            photoSettings.pictureWidth = params.getPictureSize().width;
            photoSettings.pictureHeight = params.getPictureSize().height;
            // params.setPictureSize(photoSettings.pictureWidth, photoSettings.pictureHeight);
        }
 
        final List<Integer> supportedPreviewFormats = params.getSupportedPreviewFormats();
        if (supportedPreviewFormats != null && supportedPreviewFormats.size() != 0) {
            for (int i = 0; i < supportedPreviewFormats.size(); i++) {
                if (IMAGE_FORMAT.fromNativeValue(supportedPreviewFormats.get(i)) == photoSettings.previewFormat) {
                    logger.debug("PREVIEW FORMAT: " + photoSettings.previewFormat + " is supported");
                    params.setPreviewFormat(photoSettings.previewFormat.getValue());
                    break;
                }
            }
        } else {
            logger.error("no supported preview formats for this camera");
        }
 
        final List<Integer> supportedPictureFormats = params.getSupportedPictureFormats();
        if (supportedPictureFormats != null && supportedPictureFormats.size() != 0) {
            for (int i = 0; i < supportedPictureFormats.size(); i++) {
                if (IMAGE_FORMAT.fromNativeValue(supportedPictureFormats.get(i)) == photoSettings.pictureFormat) {
                    logger.debug("PICTURE FORMAT: " + photoSettings.pictureFormat + " is supported");
                    params.setPictureFormat(photoSettings.pictureFormat.getValue());
                    break;
                }
            }
        } else {
            logger.error("no supported picture formats for this camera");
        }
 
        if ((photoSettings.jpegQuality > 0) && (photoSettings.jpegQuality <= 100)) {
            logger.debug("jpegQuality=" + photoSettings.jpegQuality);
            params.setJpegQuality(photoSettings.jpegQuality);
            params.setJpegThumbnailQuality(photoSettings.jpegQuality);
        }
 
        final List<String> supportedFlashModes = params.getSupportedFlashModes();
        if (supportedFlashModes != null && supportedFlashModes.size() != 0) {
            for (int i = 0; i < supportedFlashModes.size(); i++) {
                if (supportedFlashModes.get(i).equals(photoSettings.flashMode)) {
                    logger.debug("FLASH MODE: " + photoSettings.flashMode + " is supported");
                    params.setFlashMode(photoSettings.flashMode.getValue());
                    break;
                }
            }
        } else {
            logger.error("no supported flash modes for this camera");
        }
 
        setCameraFocus(photoSettings.focusMode);
        setCameraColorEffect(photoSettings.colorEffect);
 
        camera.setParameters(params);
        return true;
    }
В общем, кто сталкивался подобным? Как можно достичь приемлемого кач-ва?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.12.2014, 13:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как достичь приемлемого качества фото и видео, используя CameraAPI (Программирование Android):

Отправка фото в инстаграм используя апи - Программирование Android
Всем привет, пару лет назад, задавался таким вопросов, но ответ был один, нельзя. Сейчас опять возникла небольшая потребность в этом,...

Выбор обфускатора: сочетание бесплатности и приемлемого качества - C#
Понимаю что много таких тем есть ,но ничего в них не могу понять какой нормальный обфускатор,и бесплатный конечно?Или как написать свой...

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

Улучшение качества фото - Photoshop
Здравствуйте, подскажите, пожалуйста, можно ли улучшить качество фото, чтобы лица людей были узнаваемы.

Как заменить звук FLV(mp4) без потери качества видео - Видеопрограммы
Доброго времени суток! Имеется видео формат FLV потому как было скачано с ютуба качество 800x480, в это видео необходимо подставить...

Компьютер виснет при просмотре онлайн видео, видео HD качества и при сильной нагрузке. - Компьютерное железо
Здравствуйте, У меня такая проблема: Комп виснит при просмотре онлайн видео, видео HD качества и при сильной нагрузке комп,...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.12.2014, 13:41
Привет! Вот еще темы с ответами:

Как создать фото\видео альбом - Joomla
Здравствуйте. Как создать такое меню на главной странице, чтобы был заголовок фотоальбом и две фотографии которые при нажатии...

Нужно как-то достать фото и видео из IPad - Программирование iOS
Не знаю что и делать, надеюсь кто-то сможет помочь!!! Ситуация такая: обновил iPad через wifi, на экране появился значок iTunes, подключил...

Как найти человека на видео имея фото? - C++ WinAPI
Как найти человека на видео имея фото? Или хотя бы определить на видео любого человека? Есть ли какието программы для этого, я...

как выбрать качественный ноутбук для работы с видео, фото? - Выбор ноутбука
нужен очень качественный ноутбук для работы с видео, фото. Чтобы служил как можно дольше. Что посоветуете???


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru