1a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk/* 2a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * Copyright (C) 2012 The Android Open Source Project 3a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * 4a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * you may not use this file except in compliance with the License. 6a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * You may obtain a copy of the License at 7a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * 8a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * 10a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * Unless required by applicable law or agreed to in writing, software 11a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * See the License for the specific language governing permissions and 14a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk * limitations under the License. 15a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk */ 167bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 177bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkpackage com.android.gallery3d.filtershow.filters; 187bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 197bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkimport android.graphics.Bitmap; 207bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkimport android.graphics.Canvas; 21e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroardimport android.graphics.Matrix; 227bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkimport android.graphics.Paint; 2362e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunkimport android.graphics.Rect; 2462e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunkimport android.graphics.RectF; 257bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 26a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunkimport com.android.gallery3d.filtershow.imageshow.GeometryMath; 277bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkimport com.android.gallery3d.filtershow.imageshow.GeometryMetadata; 287bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 297bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunkpublic class ImageFilterGeometry extends ImageFilter { 307bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk private final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888; 317bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk private GeometryMetadata mGeometry = null; 32a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk private static final String LOGTAG = "ImageFilterGeometry"; 33a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk private static final boolean LOGV = false; 34a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk private static final int BOTH = 3; 35a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk private static final int VERTICAL = 2; 36a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk private static final int HORIZONTAL = 1; 3718fc4c1c247897db0dc74e4598a512827af816e9Ruben Brunk private static final int NINETY = 1; 3818fc4c1c247897db0dc74e4598a512827af816e9Ruben Brunk private static final int ONE_EIGHTY = 2; 3918fc4c1c247897db0dc74e4598a512827af816e9Ruben Brunk private static final int TWO_SEVENTY = 3; 407bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 417bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk public ImageFilterGeometry() { 427bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk mName = "Geometry"; 437bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk } 447bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 457bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk @Override 467bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk public ImageFilter clone() throws CloneNotSupportedException { 477bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk ImageFilterGeometry filter = (ImageFilterGeometry) super.clone(); 487bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk return filter; 497bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk } 507bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 51a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk public void setGeometryMetadata(GeometryMetadata m) { 527bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk mGeometry = m; 537bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk } 547bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 557bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk native protected void nativeApplyFilterFlip(Bitmap src, int srcWidth, int srcHeight, 567bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk Bitmap dst, int dstWidth, int dstHeight, int flip); 577bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 58a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk native protected void nativeApplyFilterRotate(Bitmap src, int srcWidth, int srcHeight, 5918fc4c1c247897db0dc74e4598a512827af816e9Ruben Brunk Bitmap dst, int dstWidth, int dstHeight, int rotate); 60a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk 61a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk native protected void nativeApplyFilterCrop(Bitmap src, int srcWidth, int srcHeight, 62a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk Bitmap dst, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight); 63a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk 64a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk native protected void nativeApplyFilterStraighten(Bitmap src, int srcWidth, int srcHeight, 65a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk Bitmap dst, int dstWidth, int dstHeight, float straightenAngle); 66a66df0c9e8106ef6a275e20ab2a47286e054fe7cRuben Brunk 67e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard @Override 68e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) { 69e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard // TODO: implement bilinear or bicubic here... for now, just use 70e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard // canvas to do a simple implementation... 71e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard // TODO: and be more memory efficient! (do it in native?) 7262e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk Rect cropBounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 73b470b229fbfd782db6758f331e4a6f918e305b02nicolasroard RectF crop = mGeometry.getCropBounds(bitmap); 7400d64dd584c6d08310a32a28e75aebc6eb8238eaRuben Brunk if (crop.width() > 0 && crop.height() > 0) 756a94446de01e8b6b034cc537ee3e65d507d47a47Ruben Brunk cropBounds = GeometryMath.roundNearest(crop); 76e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard Bitmap temp = null; 7762e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk if (mGeometry.hasSwitchedWidthHeight()) { 7862e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk temp = Bitmap.createBitmap(cropBounds.height(), cropBounds.width(), mConfig); 79e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard } else { 8062e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk temp = Bitmap.createBitmap(cropBounds.width(), cropBounds.height(), mConfig); 817bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk } 82a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk float[] displayCenter = { 83a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk temp.getWidth() / 2f, temp.getHeight() / 2f 84a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk }; 85a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk 86a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk Matrix m1 = mGeometry.buildTotalXform(bitmap.getWidth(), bitmap.getHeight(), displayCenter); 87e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard 88e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard Canvas canvas = new Canvas(temp); 89104165f1f9858bdebb2d219b077f5227203f7c02nicolasroard Paint paint = new Paint(); 90104165f1f9858bdebb2d219b077f5227203f7c02nicolasroard paint.setAntiAlias(true); 91104165f1f9858bdebb2d219b077f5227203f7c02nicolasroard paint.setFilterBitmap(true); 92104165f1f9858bdebb2d219b077f5227203f7c02nicolasroard paint.setDither(true); 93a41224997ef9be9c0d04534f7b6b9c6b933bfe05Ruben Brunk canvas.drawBitmap(bitmap, m1, paint); 94e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard return temp; 957bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk } 967bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk 977bd602506fee36f3ef0a68bfa1ba5dd1e74ca5ddRuben Brunk} 98