How to display 2 views, with a gradient-fade effect on Android? -


i want have 2 views displayed on screen - 1 camera preview, on top, while other 1 show image or google map - , live on bottom of screen.

i want have gradient-like transition between them though - there's no rough edge between them. possible have such effect?

edit: effect i'd achieve should (top part comes camera preview, while bottom part should map...):

map blending camera photo

on ios got similar effect cameraoverlay showing map , setting layer masp gradient:

cagradientlayer *gradient = [cagradientlayer layer]; gradient.frame = self.map.bounds; gradient.colors = [nsarray arraywithobjects:(id)[[uicolor colorwithwhite: 1.0 alpha: 0.0] cgcolor], (id)[[uicolor colorwithwhite: 1.0 alpha: 1.0] cgcolor], nil]; gradient.startpoint = cgpointmake(0.5f, 0.0f); gradient.endpoint = cgpointmake(0.5f, 0.5f); self.map.layer.mask = gradient; 

this possible, perhaps bit complicated. keep simple, i've put core code achieving in answer. has been noted, need 2 views this, 1 "on top of" other. "lower" 1 should surfaceview, driven maps api. "higher" 1 should show camera image faded out on it.

edit: mr_archano points out, api (now) defined such without surfaceview camera wont send out preview data. ho hum, such nature of progress, however, surmountable.

the code presents:

  • the "lower" surfaceview driven directly camera preview mechanism.
  • the "middle" surfaceview maps api.
  • the "upper" view camera data rendered achieve desired effect.

the core code therefore gives "camera preview" on "camera preview", , upper picture has been intentionally distorted it's visible @ top, fading in middle , gone @ bottom.

may suggest best way use code implement these first 4 steps on own , see working, add 2 final steps , see working, before inserting key concepts another, doubtless larger , more complex, piece of code.

first 4 steps:

  1. create custom view display top, camera, view. class renders bitmap on whatever underneath it. alpha value in each pixel in bitmap determine how of lower view let through.

    public class cameraoverlayview extends view {     private paint  paint;     private size   incomingsize;     private bitmap bitmap = null;      public cameraoverlayview(context context) {         super(context);         init();     }      public cameraoverlayview(context context, attributeset attrs) {         super(context, attrs);         init();     }      private void init() {         paint = new paint();         paint.setstyle(style.fill_and_stroke);         paint.setcolor(0xffffffff);         paint.settextsize((float) 20.0);     }      @override     protected void ondraw(canvas canvas) {         super.ondraw(canvas);          int width  = canvas.getwidth();         int height = canvas.getheight();          canvas.drawbitmap(bitmap, 0.0f, 0.0f, paint);     } } 
  2. put 3 views in frame them set tofill_parent in both directions. first 1 "underneath" (the surfaceview the camera preview works). second 1 "in middle" (the surface view maps or whatever). third "on top" (the view faded camera image).

    <surfaceview     android:id="@+id/beneathsurfaceview"     android:layout_width="fill_parent"     android:layout_height="fill_parent" />  <surfaceview     android:id="@+id/middlesurfaceview"     android:layout_width="fill_parent"     android:layout_height="fill_parent" />  <com.blah.blah.blah.cameraoverlayview     android:id="@+id/abovecameraview"     android:layout_width="fill_parent"     android:layout_height="fill_parent" /> 

  3. a stripped down main activity set camera, , send automatic preview image (bottom) surfaceview , preview image data processing routine. sets callback catch preview data. these 2 run in parallel.

    public class cameraoverlay extends activity implements surfaceholder.callback2 {      private surfaceview       backsv;     private cameraoverlayview camerav;     private surfaceholder camerah;     private camera        camera=null;      private camera.previewcallback cameracpcb;      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.camera_overlay);          // 2 views                 backsv  = (surfaceview) findviewbyid(r.id.beneathsurfaceview);         camerav = (cameraoverlayview) findviewbyid(r.id.abovecameraview);          // back: putting camera on sv (replace whatever driving sv)         camerah  = backsv.getholder();         camerah.addcallback(this);          // front: getting data camera (for front view)         cameracpcb = new camera.previewcallback () {             @override             public void onpreviewframe(byte[] data, camera camera) {                 camerav.acceptcameradata(data, camera);             }         };     }      // making camera run , stop state changes     @override     public void onresume() {         super.onresume();         camera = camera.open();         camera.startpreview();     }      @override     public void onpause() {         super.onpause();         camera.setpreviewcallback(null);         camera.stoppreview();         camera.release();         camera=null;     }      private void cameraimagetoviewon() {         // front         camerav.setincomingsize(camera.getparameters().getpreviewsize());         camera.setpreviewcallback(cameracpcb);     }      private void cameraimagetoviewoff() {         // front         camera.setpreviewcallback(null);     }      // callbacks mean camera stuff ...     @override     public void surfacechanged(surfaceholder holder, int format, int width, int height) {         // if preview can change or rotate, take care of events here.         // make sure stop preview before resizing or reformatting it.          if (holder == null) return;          // stop preview before making changes         try {             cameraimagetoviewoff(); // front             camera.stoppreview();             } catch (exception e){             // ignore: tried stop non-existent preview         }          // set preview size , make resize, rotate or reformatting changes here          // start preview new settings         try {             camera.setpreviewdisplay(holder); //back             camera.startpreview();             cameraimagetoviewon(); // front         } catch (exception e){         }     }      @override     public void surfacecreated(surfaceholder holder) {         try {             camera.setpreviewdisplay(holder); //back             camera.startpreview();             cameraimagetoviewon(); // front         } catch (ioexception e) {         }            }      @override     public void surfacedestroyed(surfaceholder holder) { }      @override     public void surfaceredrawneeded(surfaceholder holder) {     } } 

    some things missing:

    • ensuring camera image right orientation
    • ensuring camera preview image optimal size

  4. now, add 2 functions view created in step one. first ensures view knows size of incoming image data. second receives preview image data, turns bitmap, distorting along way both visibility , demonstrate alpha fade.

    public void setincomingsize(size size) {     incomingsize = size;     if (bitmap != null) bitmap.recycle();     bitmap = bitmap.createbitmap(size.width, size.height, bitmap.config.argb_8888); }  public void acceptcameradata(byte[] data, camera camera) {     int width  = incomingsize.width;     int height = incomingsize.height;      // bitmap want fill image     int numpixels = width*height;      // buffer fill fill bitmap     intbuffer intbuffer = intbuffer.allocate(width*height);     // if you're reusing buffer, next line imperative refill start, - if not practice     intbuffer.position(0);      // each pixel, 1 @ time     int y;     int xby2, yby2;     int r, g, b, alpha;     float u, v, yf;     (int y = 0; y < height; y++) {         // set transparency based on how far down image are:         if (y<200) alpha = 255;          // image @ top         else if (y<455) alpha = 455-y;   // fade on next 255 lines         else alpha = 0;                  // nothing after         // speed's sake, should break out of loop once alpha 0 ...          (int x = 0; x < width; x++) {             // y value, stored in first block of data             // logical "and 0xff" needed deal signed issue             y = data[y*width + x] & 0xff;              // u , v values, stored after y values, 1 per 2x2 block             // of pixels, interleaved. prepare them floats correct range             // ready calculation later.             xby2 = x/2;             yby2 = y/2;             u = (float)(data[numpixels + 2*xby2 + yby2*width] & 0xff) - 128.0f;             v = (float)(data[numpixels + 2*xby2 + 1 + yby2*width] & 0xff) - 128.0f;              // yuv -> rgb conversion             yf = 1.164f*((float)y) - 16.0f;             r = (int)(yf + 1.596f*v);             g = 2*(int)(yf - 0.813f*v - 0.391f*u); // distorted show effect             b = (int)(yf + 2.018f*u);              // clip rgb values 0-255             r = r < 0 ? 0 : r > 255 ? 255 : r;             g = g < 0 ? 0 : g > 255 ? 255 : g;             b = b < 0 ? 0 : b > 255 ? 255 : b;              // put pixel in buffer             intbuffer.put(color.argb(alpha, r, g, b));         }     }      // buffer ready read     intbuffer.flip();      // push pixel information buffer onto bitmap.     bitmap.copypixelsfrombuffer(intbuffer);      this.invalidate(); } 

    notes on second routine:

that code shows basic idea. step next phase:

  1. set camera surface view sufficiently small hide behind non-faded section of top view. ie, change android:layout_height to, say, 60dp.

  2. set middle surfaceview receive map information.


Comments

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -