alexvasilkov / GestureViews

ImageView and FrameLayout with gestures control and position animation
Apache License 2.0
2.37k stars 384 forks source link

Reissue about Canvas draw too large bitmap problem. #156

Closed deverhjj closed 4 years ago

deverhjj commented 4 years ago

I think because of GestureImageView force using Matrix to transform image and cause Glide not downsample image.

155

GestureImageView


public GestureImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        ensureControllerCreated();
        controller.getSettings().initFromAttributes(context, attrs);
        controller.addOnStateChangeListener(new GestureController.OnStateChangeListener() {
            @Override
            public void onStateChanged(State state) {
                applyState(state);
            }

            @Override
            public void onStateReset(State oldState, State newState) {
                applyState(newState);
            }
        });
        // This is the point
        setScaleType(ImageView.ScaleType.MATRIX);
    }```
// Glide code
@NonNull
  public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);
    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
      // Clone in this method so that if we use this RequestBuilder to load into a View and then
      // into a different target, we don't retain the transformation applied based on the previous
      // View's scale type.
      switch (view.getScaleType()) {
        case CENTER_CROP:
          requestOptions = requestOptions.clone().optionalCenterCrop();
          break;
        case CENTER_INSIDE:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case FIT_CENTER:
        case FIT_START:
        case FIT_END:
          requestOptions = requestOptions.clone().optionalFitCenter();
          break;
        case FIT_XY:
          requestOptions = requestOptions.clone().optionalCenterInside();
          break;
        case CENTER:
        case MATRIX:  // This is the point
        default:
          // Do nothing.
      }
    }
   ...
}
alexvasilkov commented 4 years ago

Thanks for the extra information. So the problem is that you were relying on Glide's implicit downsampling behavior when image's scale type is set to something other than "center" or "matrix".

Note though, that there is no way this library can allow you to use anything ragher than "matrix" because it is used for image state control. Although I don't think it will be good if Glide will crop bitmaps to fit enclosing ImageView anyway, what will be the purpose of this library if it cannot show full (uncropped) images?

The best fix for this issue will be to control images size from backend side, it will be much more efficient than downloading huge images and then downsampling them locally. If backend is out of your control then you can explicitly configure Glide to downsample images for you. As I already mentioned this library does not control bitmaps loading and it just shows whatever was loaded into it.

BTW, I don't think it was worth to create a new issue for it, it is now a duplicate of #103, #108 and #155. I'll close it again as there is nothing I can do here.