0

Fresco hat integrierte Unterstützung für kreisförmige Bilder und abgerundete Ecke, aber was ist mit anderen Formen wie Diamant oder Parallelogramm, etc?Android Fresco: Zeichnung verschiedener Art von Bildformen

Es ist einfach mit dem Standard-ImageView über benutzerdefinierte Zeichensätze, die BitmapShader verwendet. Zum Beispiel empfängt der folgende benutzerdefinierte Drawable das Bild Bitmap und eine Steigung Höhe ein ein Image aussehen wie dieses Bild zu machen:

enter image description here

public class MaskDrawable extends Drawable { 
    private Paint mPaint; 
    private Path mPath; 
    private int mSlopeHeight; 

    public MaskDrawable(Bitmap bitmap, int slopeHeight) { 
     BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setShader(shader); 
     mSlopeHeight = slopeHeight; 

     mPath = new Path(); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     Rect bounds = getBounds(); 

     mPath.moveTo(0, 0); 
     mPath.lineTo(0, bounds.bottom); 
     mPath.lineTo(bounds.right, bounds.bottom - mSlopeHeight); 
     mPath.lineTo(bounds.right, 0); 
     canvas.drawPath(mPath, mPaint); 
    } 

Um das zu tun mit Fresko, ich die Bitmap des Bildes benötigen aber ich bin mir nicht sicher, wie ich das machen soll. Ich habe gelesen, dass ich die Bitmap direkt von der ImagePipeline bekommen kann, aber das sind viele Fehler, die damit einhergehen. In einem Fall ist das zurückgegebene Bitmap kurzlebig und sollte nicht zum Zeichnen auf dem Bildschirm verwendet werden, in dem anderen Fall erhalte ich eine CloseableReference, die ich irgendwann freigeben muss, was mir nicht klar ist. Was ich bisher auf dem Netz gesehen ist Code ähnlich wie diese für die Bitmap immer:

ImagePipeline imagePipeline = Fresco.getImagePipeline(); 

     ImageRequest imageRequest = ImageRequestBuilder 
       .newBuilderWithSource(uri) 
       .setRequestPriority(Priority.HIGH) 
       .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH) 
       .build(); 

     DataSource<CloseableReference<CloseableBitmap>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, getContext()); 

     DataSubscriber<CloseableReference<CloseableBitmap>> dataSubscriber = 
       new BaseDataSubscriber<CloseableReference<CloseableBitmap>>() { 
        @Override 
        protected void onNewResultImpl(DataSource<CloseableReference<CloseableBitmap>> dataSource) { 
         mBitmapRef = dataSource.getResult(); 
         // Get the bitmap here and use it in my custom drawable? 
        } 

        @Override 
        protected void onFailureImpl(DataSource<CloseableReference<CloseableBitmap>> dataSource) { 
        } 
       }; 

     dataSource.subscribe(dataSubscriber, UiThreadImmediateExecutorService.getInstance()); 

Ich habe das noch nicht ausprobiert und habe mich gefragt, ob jemand eine funktionierende Lösung anstelle der Bits und Bytes liefern kann mich bin so weit von verschiedenen Orten zusammengekommen. Es muss richtig gemacht werden oder sonst kann ich leicht Speicher verlieren, was die ganze Idee, Fresco von Anfang an zu verwenden, übertrifft.

Antwort

-1

Sie müssen nicht und auch nicht empfehlen, imagepipeline zu verwenden, wie Sie mit Ansicht beschäftigen.

Eine Möglichkeit besteht darin, diese Bitmap im Postprozessor zu verwalten. Sie müssen die Prozessmethode überschreiben, dieselbe BitmapShader-, paint-, Canvas-Implementierung verwenden, PlatformBitmapFactory createBitmap verwenden, um eine zu entfernende Bitmap CloseableReference zu erstellen, und schließlich die Referenz schließen, wenn Sie mit der Bitmap fertig sind.

Weitere http://frescolib.org/docs/modifying-image.html

EDIT

Im Folgenden die endgültige Umsetzung kam ich mit nach Hilfe von Jie Wang bekommen. Das folgende Code-Snippet platziert das Bild in der Form, die ich in der Frage dargestellt habe.

mSimpleDraweeView = (SimpleDraweeView) findViewById(R.id.shaped_picture); 
final int slopeHeight = 100; 

Postprocessor maskProcessor = new BasePostprocessor() { 
    @Override 
    public CloseableReference<Bitmap> process(Bitmap sourceBitmap, PlatformBitmapFactory bitmapFactory) { 
     // Get the size of the downloaded bitmap 
     final int width = sourceBitmap.getWidth(); 
     final int height = sourceBitmap.getHeight(); 

     // Create a new bitmap and use it to draw the shape that we want. 
     CloseableReference<Bitmap> bitmapRef = bitmapFactory.createBitmap(width, height); 
     try { 
      Bitmap destBitmap = bitmapRef.get(); 

      // Create canvas using the new bitmap we created earlier 
      Canvas canvas = new Canvas(destBitmap); 

      // Set up the Paint we will use for filling in the shape 
      // BitmapShader will fill the shape with the downloaded bitmap 
      BitmapShader shader = new BitmapShader(sourceBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
      Paint paint = new Paint(); 
      paint.setAntiAlias(true); 
      paint.setShader(shader); 

      // Set up the actual shape. Modify this part with any shape you want to have. 
      Path path = new Path(); 
      path.moveTo(0, 0); 
      path.lineTo(0, height); 
      path.lineTo(width, height - slopeHeight); 
      path.lineTo(width, 0); 

      // Draw the shape and fill it with the paint 
      canvas.drawPath(path, paint); 

      return CloseableReference.cloneOrNull(bitmapRef); 
     } 
     finally { 
      CloseableReference.closeSafely(bitmapRef); 
     } 
    } 
}; 

ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) 
     .setPostprocessor(maskProcessor) 
     .build(); 

DraweeController controller = Fresco.newDraweeControllerBuilder() 
     .setImageRequest(request) 
     .setOldController(mSimpleDraweeView.getController()) 
     .build(); 

mSimpleDraweeView.setController(controller); 
+0

Ich habe die Antwort aktualisiert, um die konkrete Lösungsimplementierung zu haben, falls jemand anderes auf dieses Problem stoßen sollte. –