matrix - Camera PreviewView is streched in some android devices -
right im playing api2 camera of google , im having problems code. had 2 different camerasessions, 1 video , 1 images. more efficient change code use unique session , make app more efficient.
after this, camera preview not working adequately. when im using 4:3 aspect ratio preview become streched @ height. in other way looks fine when im using 16:9 ratio. in both cases pictures looks fine, mean, preview doesnt work correctly pictures taked, have correct aspect ratio.
i check different post same problem: camera preview stretched on few android devices
but different answers didnt me. know problem inside onmeasure() , settransformmatrix() or onlayoutchangelistener()
methods, dont know iḿ doing wrong.
ignore code rotation, right dynamic. enter @ else condition.
here code:
private onlayoutchangelistener mlayoutlistener = new onlayoutchangelistener() { @override public void onlayoutchange(view v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldright, int oldbottom) { log.d(tag, "[onlayoutchange] " + mcameraui.gettextureview().getmeasuredwidth() + "x" + mcameraui.gettextureview().getmeasuredheight()); int width = right - left; int height = bottom - top; if (mpreviewwidth != width || mpreviewheight != height || (morientationresize != mprevorientationresize) || maspectratioresize || morientationchanged) { log.i(tag, "[onlayoutchange] layout changed"); mpreviewwidth = width; mpreviewheight = height; log.i(tag, "[onlayoutchange] preview size: "+ mpreviewwidth + "x" + mpreviewheight); settransformmatrix(width, height); mcontroller.onscreensizechanged((int) msurfacetextureuncroppedwidth, (int) msurfacetextureuncroppedheight); maspectratioresize = false; morientationchanged = true; } } };
settransform
private void settransformmatrix(int width, int height) { log.i(tag, "screen: " + mpreviewwidth + "x" + mpreviewheight); mmatrix = new matrix(); //mcameraui.gettextureview().gettransform(mmatrix); float scalex = 1f, scaley = 1f; float scaledtexturewidth, scaledtextureheight; maspectratio= (float)height/(float)width; if (maspectratio==(4f / 3f)){ scaledtexturewidth = math.max(width, (int) (height / maspectratio)); scaledtextureheight = math.max(height, (int) (width * maspectratio)); log.i(tag, "[photouimanager]: aspect ratio 4:3=" + scaledtexturewidth + "x" + scaledtextureheight ); } else{ scaledtexturewidth = math.max(width, (int) (height / maspectratio)); scaledtextureheight = math.max(height, (int) (width * maspectratio)); log.i(tag, "[photouimanager]: aspect ratio 16:9=" + scaledtexturewidth + "x" + scaledtextureheight ); } if (msurfacetextureuncroppedwidth != scaledtexturewidth || msurfacetextureuncroppedheight != scaledtextureheight) { log.e(tag,"mi surfacewidth = " + msurfacetextureuncroppedwidth + "and mi scaledwidth=" + scaledtexturewidth); log.e(tag,"mi surfaceheigh = " + msurfacetextureuncroppedheight + "and mi scaledheight=" + scaledtextureheight); msurfacetextureuncroppedwidth = scaledtexturewidth; msurfacetextureuncroppedheight = scaledtextureheight; log.e(tag,"surfaces: " + msurfacetextureuncroppedwidth + "x" + msurfacetextureuncroppedheight); if (msurfacetexturesizelistener != null) { msurfacetexturesizelistener.onsurfacetexturesizechanged( (int) msurfacetextureuncroppedwidth, (int) msurfacetextureuncroppedheight); } } scalex = scaledtexturewidth / width; scaley = scaledtextureheight / height; mmatrix.setscale(scalex, scaley, scaledtexturewidth/2, scaledtextureheight/2); log.e(tag, "scale: x= " + scalex + " y=" + scaley + "width= " + scaledtexturewidth + "height= " + scaledtextureheight); // init position (this seems necessary when ratio 16/9 mcameraui.gettextureview().setx(0); mcameraui.gettextureview().sety(0); // translate preview rotation aspect ration 4/3 if (maspectratio == 4f / 3f) { log.e(tag, "aspect ratio standard"); float verticaltranslateoffset = (mcameraui.gettextureview().getmeasuredheight() - scaledtextureheight) / 2; float horizontaltranslateoffset = (mcameraui.gettextureview().getmeasuredwidth() - scaledtexturewidth) / 2; int rotation = camerautil.getdisplayrotation(mactivity); switch (rotation) { case 0: // phone portrait; translate preview mcameraui.gettextureview().sety(-verticaltranslateoffset); mfaceview.setstandardpreviewtranslationoffset(-verticaltranslateoffset); mfocusview.setstandardpreviewtranslationoffset(-verticaltranslateoffset); break; case 90: // phone landscape: translate preview left mcameraui.gettextureview().setx(-horizontaltranslateoffset); mfaceview.setstandardpreviewtranslationoffset(-horizontaltranslateoffset); mfocusview.setstandardpreviewtranslationoffset(-horizontaltranslateoffset); break; case 180: // phone upside down: translate preview bottom mcameraui.gettextureview().sety(verticaltranslateoffset); mfaceview.setstandardpreviewtranslationoffset(verticaltranslateoffset); mfocusview.setstandardpreviewtranslationoffset(verticaltranslateoffset); break; case 270: // reverse landscape: translate preview right mcameraui.gettextureview().setx(horizontaltranslateoffset); mfaceview.setstandardpreviewtranslationoffset(horizontaltranslateoffset); mfocusview.setstandardpreviewtranslationoffset(horizontaltranslateoffset); break; } } else { log.e(tag, "aspect ratio full"); mfaceview.setstandardpreviewtranslationoffset(0); mfocusview.setstandardpreviewtranslationoffset(0); } mrenderoverlay.updatelayout(); mcameraui.gettextureview().settransform(mmatrix); rectf previewrect = new rectf(0, 0, width, height); mcontroller.onpreviewrectchanged(camerautil.rectftorect(previewrect)); }
onmeasure
protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); int width = measurespec.getsize(widthmeasurespec); int height = measurespec.getsize(heightmeasurespec); log.d(tag, "onmeasure previous. width x height [" + widthmeasurespec + " = " + width + "x" + heightmeasurespec + " = " + height + "]"); int rotation = ((activity) getcontext()).getwindowmanager().getdefaultdisplay().getrotation(); boolean isinhorizontal = surface.rotation_90 == rotation || surface.rotation_270 == rotation; int newwidth; int newheight; if (isinhorizontal) { newheight = getmeasuredheight(); newwidth = (int) (newheight * maspectratio); } else { newwidth = getmeasuredwidth(); newheight = (int) (newwidth * maspectratio); } setmeasureddimension(newwidth, newheight); log.d(tag, "onmeasure. width x height [" + newwidth + "x" + newheight + "]"); }
solved!
i had default values buffersize of texture, restarted when inicializated new session or after change after ratio. width , height values texture not updated ratio, becomes streched again , again.
i solved changing defaultbuffersize previewsizes update change ratio.
public void createcamerapreviewsession(size previewsize, surface recordingsurface) { try { if (mcapturesession != null) { mcapturesession.stoprepeating(); mcapturesession.close(); mcapturesession = null; } surfacetexture texture = mtextureview.getsurfacetexture(); assert texture != null; list<surface> surfaces = new arraylist<surface>(); // configure size of default buffer size of camera preview want. texture.setdefaultbuffersize(previewsize.getwidth(),previewsize.getheight()); ; // output surface need start preview. surface surface = new surface(texture); .......
Comments
Post a Comment