- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在寻求帮助解决我在使用 Grafika's CameraCaptureActivity 时遇到的问题代码。我想构建一个可以记录相机并显示预览的应用程序,所以这个示例和代码看起来正是我想要的,到目前为止一切都很好,这个问题的应用程序。
我遇到的问题是,当相机预览大小与我用来显示预览的 GLSurfaceView
的确切大小不匹配时,它会显示拉伸(stretch)的预览。
这是它的样子:
正如您所见,它被水平拉伸(stretch)了,因为笔记纸是一个完美的正方形。
对于三星 Galaxy S4 上的这个精确示例,相机预览尺寸为 1280x720
(使用 Camera2
API 从可用预览尺寸中提取),GLSurfaceView
为 1920x1080
以覆盖整个屏幕。
什么时候出现?
当 SurfaceView 相对于 Camera 输出放大时会出现问题,即使我始终确保比率保持正确 (1920x1080
= 1,5 * 1280x720
) .
您使用的是什么代码?
我使用Grafika的代码,包括:
一些日志?
这是 SurfaceFlinger 转储的样子:
Hardware Composer state (version 01030000):
mDebugForceFakeVSync=0
Display[0] configurations (* current):
* 0: 1080x1920, xdpi=442.450989, ydpi=439.351013, secure=1 refresh=16666667
numHwLayers=3, flags=00000000
type | handle | hint | flag | tr | blnd | format | source crop(l,t,r,b) | frame | dirtyRect | name
------------+----------+----------+----------+----+-------+----------+-----------------------------------+---------------------------+-------------------
HWC | b3b12ba0 | 0002 | 0000 | 00 | 0100 | RGB_888 | 0.0, 0.0, 1080.0, 1920.0 | 0, 0, 1080, 1920 | [ 0, 0, 1080, 1920] | SurfaceView
HWC | b3d12740 | 0002 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1065.0, 1905.0 | 0, 0, 1065, 1905 | [ 0, 0, 1065, 1905] | com.mybundle.myapp/com.mybundle.myapp.activity.MyActivity
FB TARGET | b6a55c40 | 0000 | 0000 | 00 | 0105 | RGBA_8888 | 0.0, 0.0, 1080.0, 1920.0 | 0, 0, 1080, 1920 | [ 0, 0, 0, 0] | HWC_FRAMEBUFFER_TARGET
Layer 0xb4094000 (SurfaceView)
Region transparentRegion (this=0xb4094160, count=1)
[ 0, 0, 0, 0]
Region visibleRegion (this=0xb4094008, count=1)
[ 0, 0, 1920, 1080]
layerStack= 0, z= 21015, pos=(0,0), size=(1920,1080), crop=( 0, 0,1920,1080), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000002, tr=[1.00, 0.00][0.00, 1.00]
client=0xb66190c0
format= 4, activeBuffer=[1080x1920:1536, 3], queued-frames=0, mRefreshPending=0
mTexName=116 mCurrentTexture=0
mCurrentCrop=[0,0,0,0] mCurrentTransform=0x7
mAbandoned=0
-BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[1920x1080], default-format=4, transform-hint=04, FIFO(0)={}
>[00:0xb1c18500] state=ACQUIRED, 0xb3b12ba0 [1080x1920:1536, 3]
相机预览尺寸代码?
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
// Retrieve display size
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
// Choose the sizes for camera preview
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
displaySize.x, displaySize.y, captureWidth, captureHeight);
private static Size chooseOptimalSize(Size[] choices, int screenWidth, int screenHeight, int captureWidth, int captureHeight)
{
// Collect the supported resolutions that are at least as big as the screen && wanted capture size
List<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are at least as big as the wanted capture size but < to screensize
List<Size> smallerButEnough = new ArrayList<>();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * captureHeight / captureWidth) {
if( option.getWidth() >= screenWidth && option.getHeight() >= screenHeight )
{
bigEnough.add(option);
}
else
{
smallerButEnough.add(option);
}
}
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0)
{
return Collections.min(bigEnough, new CompareSizesByArea());
}
// Pick the biggest of those, assuming we found any
else if( smallerButEnough.size() > 0 )
{
return Collections.max(smallerButEnough, new CompareSizesByArea());
}
else
{
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
你尝试了什么?
我一开始以为是 Camera2
的问题,所以我尝试只使用旧的 Camera API,但结果是一样的。
然后我以为是比例问题,但是你可以看到这里的比例水平和垂直都还可以。
我敢打赌,在调整 Surface 大小时会应用 OpenGL 转换,但我是 OpenGL 的菜鸟,所以我找不到任何有用的方法。我尝试添加这些行,但没有帮助:
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.d(TAG, "onSurfaceChanged " + width + "x" + height);
gl.glViewport(0, 0, width, height);
gl.glClear(GLES10.GL_COLOR_BUFFER_BIT | GLES10.GL_DEPTH_BUFFER_BIT);
}
另一个例子,来自 Grafika:
这是问题的另一个示例,直接来自 Grafika 应用程序。
手机:Galaxy S3 Neo(GT-I9301L
)- Android 4.4.2
手机有一个 1280x720
屏幕,相机以 640x480
分辨率打开,以 573x430
显示。这是它的样子:
SurfaceFlinger 日志:
Hardware Composer state (version 1030000):
mDebugForceFakeVSync=0
Display[0] : 720x1280, xdpi=304.799011, ydpi=306.716003, refresh=16666667
numHwLayers=4, flags=00000000
type | handle | hints | flags | tr | blend | format | source crop | frame name
------------+----------+----------+----------+----+-------+----------+---------------------------------+--------------------------------
HWC | b84a3d18 | 00000002 | 00000000 | 00 | 00100 | 00000002 | [ 0.0, 0.0, 430.0, 573.0] | [ 32, 353, 462, 926] SurfaceView
HWC | b841b080 | 00000002 | 00000000 | 00 | 00105 | 00000001 | [ 0.0, 0.0, 670.0, 1280.0] | [ 0, 0, 670, 1280] com.android.grafika/com.android.grafika.CameraCaptureActivity
HWC | b8423250 | 00000002 | 00000000 | 00 | 00105 | 00000001 | [ 0.0, 0.0, 50.0, 1280.0] | [ 670, 0, 720, 1280] StatusBar
FB TARGET | b8412d50 | 00000000 | 00000000 | 00 | 00105 | 00000001 | [ 0.0, 0.0, 720.0, 1280.0] | [ 0, 0, 720, 1280] HWC_FRAMEBUFFER_TARGET
+ Layer 0xb8416080 (SurfaceView) id=112
Region transparentRegion (this=0xb84169d0, count=1)
[ 0, 0, 0, 0]
Region visibleRegion (this=0xb8416088, count=1)
[353, 258, 926, 688]
layerStack= 0, z= 21015, pos=(353,258), size=( 573, 430), crop=( 0, 0, 573, 430), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000000, tr=[1.00, 0.00][0.00, 1.00]
client=0xb841d7c8
format= 4, activeBuffer=[ 430x 573: 448, 2], queued-frames=0, mRefreshPending=0
mTexName=95 mCurrentTexture=1
mCurrentCrop=[0,0,0,0] mCurrentTransform=0x7
mAbandoned=0
-BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[573x430], default-format=4, transform-hint=04, FIFO(0)={}
[00:0xb84439a8] state=FREE , 0xb849a528 [ 430x 573: 448, 2]
>[01:0xb8421128] state=ACQUIRED, 0xb84a3d18 [ 430x 573: 448, 2]
[02:0xb84238e8] state=FREE , 0xb84432f8 [ 430x 573: 448, 2]
Grafika 的应用日志:
04-18 18:06:49.954 14383-14383/com.android.grafika D/Grafika: onCreate complete: com.android.grafika.CameraCaptureActivity@42adc288
04-18 18:06:49.954 14383-14383/com.android.grafika D/Grafika: onResume -- acquiring camera
04-18 18:06:50.064 14383-14383/com.android.grafika D/Grafika: Camera preferred preview size for video is 1920x1080
04-18 18:06:50.064 14383-14383/com.android.grafika D/Grafika-AFL: Setting aspect ratio to 1.3333333333333333 (was -1.0)
04-18 18:06:50.064 14383-14383/com.android.grafika D/Grafika: onResume complete: com.android.grafika.CameraCaptureActivity@42adc288
04-18 18:06:50.064 14383-32312/com.android.grafika D/Grafika: setCameraPreviewSize
04-18 18:06:50.094 14383-14383/com.android.grafika D/Grafika-AFL: onMeasure target=1.3333333333333333 width=[MeasureSpec: EXACTLY 1216] height=[MeasureSpec: EXACTLY 526]
04-18 18:06:50.094 14383-14383/com.android.grafika D/Grafika-AFL: new size=701x526 + padding 0x0
04-18 18:06:50.094 14383-14383/com.android.grafika D/Grafika-AFL: onMeasure target=1.3333333333333333 width=[MeasureSpec: EXACTLY 1216] height=[MeasureSpec: EXACTLY 430]
04-18 18:06:50.094 14383-14383/com.android.grafika D/Grafika-AFL: new size=573x430 + padding 0x0
04-18 18:06:50.124 14383-32312/com.android.grafika D/Grafika: onSurfaceCreated
04-18 18:06:50.134 14383-32312/com.android.grafika D/Grafika: Created program 3 (TEXTURE_EXT)
04-18 18:06:50.144 14383-32312/com.android.grafika D/Grafika: onSurfaceChanged 573x430
04-18 18:06:50.144 14383-32312/com.android.grafika D/Grafika: Updating filter to 0
04-18 18:06:50.154 14383-14383/com.android.grafika D/Grafika: onItemSelected: 0
04-18 18:06:50.154 14383-14383/com.android.grafika D/Grafika: CameraHandler [Handler (com.android.grafika.CameraCaptureActivity$CameraHandler) {42aeec70}]: what=0
04-18 18:06:50.514 14383-14383/com.android.grafika D/Grafika-AFL: onMeasure target=1.3333333333333333 width=[MeasureSpec: EXACTLY 1216] height=[MeasureSpec: EXACTLY 526]
04-18 18:06:50.514 14383-14383/com.android.grafika D/Grafika-AFL: new size=701x526 + padding 0x0
04-18 18:06:50.514 14383-14383/com.android.grafika D/Grafika-AFL: onMeasure target=1.3333333333333333 width=[MeasureSpec: EXACTLY 1216] height=[MeasureSpec: EXACTLY 430]
04-18 18:06:50.514 14383-14383/com.android.grafika D/Grafika-AFL: new size=573x430 + padding 0x0
04-18 18:06:50.544 14383-14383/com.android.grafika D/AbsListView: onVisibilityChanged() is called, visibility : 4
04-18 18:06:50.544 14383-14383/com.android.grafika D/AbsListView: unregisterIRListener() is called
所以...
如果你们中有人知道如何让它发挥作用,我很乐意听取他的意见。
谢谢!
最佳答案
我为我上次的回答感到抱歉,它很愚蠢并且没有解决问题。但我创建了另一个解决方案,并在 5 台使用不同相机宽高比的设备上对其进行了测试。据我了解,您正在使用 Grafika 代码。尝试删除 parms.setRecordingHint(true);
所以现在我只使用param.setPictureSize()
在相机参数中具有相同的纵横比。我还用那个方面设置了 gl view 的大小,我自己做的。在 grafika 中它使用固定大小,afaik。希望对你有帮助。
param.setPreviewSize()
关于使用 Grafika CameraCapture 代码拉伸(stretch)的 Android 相机预览,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36595504/
我想创建一个随页面宽度变化的页眉。 我的标题由三部分组成,固定宽度的两侧和可拉伸(stretch)的中间部分。 我使用 displa
我正在尝试在导航栏下方创建一列内容,以便内容的宽度与导航栏的宽度完全匹配。事实证明这比我预期的要困难。 给定这样的东西: link
我有一个大小为 12*30 的字符串的图像。我想创建一个动画,让它给人一种拉伸(stretch)字符串的感觉。我通过缩放图像来做到这一点,但我面临的问题是缩放图像没有发生碰撞。它仅出现在原始图像大小的
在 Silverlight 中,如何拉伸(stretch) Line 的宽度以填充作为子元素的 StackPanel 的宽度?更喜欢 XAML 解决方案,而不是代码隐藏。这是我在 WPF 中的操作方法
QML 怎么可能?自动拉伸(stretch)元素以使其所有子元素都适合它?以及如何指定间距?例如,我想在文本周围有一个矩形。矩形应该有一些内部间距。 如果我写以下内容,则矩形的大小为 0,0。 Rec
我已经习惯了使用 matlab,现在正在尝试转换 matplotlib 和 numpy。 matplotlib 中是否有一种方法可以让您绘制的图像占据整个图形窗口。 import numpy as n
我有一个(简化的)2x2 网格,里面有三个控件。左控制在两行上延伸。
假设我有 3 个大小不匹配的列表,[3, 7, 6]、[12, 67, 89, 98] 和 [1, 2, 3, 4, 5, 6, 7]我想要一个函数来执行此操作: >>> stretch([3, 7,
如果 Image 被 Stretched,我可以获取 Height 和 Width 吗>UniformToFill? 我尝试了 Width 和 Height 属性,但它们始终是 NaN。 最佳答案 如
当我为微调器使用我自己的背景主题时,它是拉伸(stretch)图标。 我的微调器代码是: 我的 spinner.xml 是: 和我从 sdk 4 复制的图
我正在尝试在 OpenGL 中创建一个简单的 GUI。我创建了一张图片,以便我可以引用它并使解释更简单: 当我将按钮 (32x32) 的纹理应用到大小为 120x20 的四边形多边形(即不是矩形作为纹
SurfaceTexture 预览被拉伸(stretch)了!我正在开发一个 camera2 应用程序。每个设备都工作不好。视频和照片的预览被拉伸(stretch)。 public class Cam
我使用一些ImageButtons 创建了一个Android layout。我的布局在小屏幕(例如 3.6 英寸到 4.2 英寸)上运行良好,但是当我在 7 英寸或 9 英寸平板电脑上使用我的应用程序
我在拉伸(stretch) GridView 以适应显示宽度时遇到问题。任何人都知道如何解决这个问题?我希望 GridView 占据整个宽度,包括蓝色标记的字段(见下图)
我使用位图作为 Activity 的背景。自定义背景代码为: 但是它位于中间,并没有占据整个屏幕空间。我怎样才能让它填满所有可用空间?我尝试将宽度和高度设置为 fill_parent。 谢谢 最
所以我最近一直在为 iOS 开发应用程序,但遇到了一个难题。我正在制作一个迷你合成器,然后开始制作 GUI。我开始制作键盘(目前为 2 个 Octave )并测量了白键的大致长度。一切都很好,直到我在
好的,所以我在 slider 内有一个图像,但它不能正确缩放。 先小后伸,想一直伸到底,怎么实现? 看一下截图(忽略第二张截图中的红色部分): 还有CSS: .slider-wrapper {
我有下面的 HTML,我希望容器 div 拉伸(stretch)到窗口的整个高度。这对 wine 有效,但是当您移除容器内的两个蓝色 div 时会发生什么?容器延伸到其中蓝色 div 的底部,但不会延
我正尝试在 this example 之后制作背景,但我需要嵌套 2 个容器。 我的代码看起来像这样: XHTML:
这是关于用颜色填充背景。 我正在构建 this project 的 SwiftUI 版本.这是一个选项卡式应用程序(测试工具)。 This is my Working Project 我要做的第一件事
我是一名优秀的程序员,十分优秀!