android mirroring imageresource in src of imagebutton - android

I set the ImageResource of an ImageButton programmatically, while itself is created in xml:
<ImageButton
android:id="#+id/id_of_image_button"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_below="#+id/id_of_other_image_button"
android:layout_centerHorizontal="true"
android:background="#drawable/background_of_image_button"
android:contentDescription="#string/description_of_image_button"
android:onClick="onButtonClick"
android:scaleType="fitCenter" />
in java I set the src (depends on other code...)
ImageButton ib = (ImageButton) findViewById(R.id.id_of_image_button);
ib.setImageResource(R.drawable.src_of_image_button);
How can I mirror the ImageResource (src only, NOT the background)? Is there any solution (in Java/XML) which doesn't blow up the simple code? ;)

Add this method to your code
private final static Bitmap makeImageMirror(final Bitmap bmp)
{
final int width = bmp.getWidth();
final int height = bmp.getHeight();
// This will not scale but will flip on the X axis.
final Matrix mtx = new Matrix();
mtx.preScale(-1, 1);
// Create a Bitmap with the flip matrix applied to it.
final Bitmap reflection = Bitmap.createBitmap(bmp, 0, 0, width, height, mtx, false);
// Create a new Canvas with the bitmap.
final Canvas cnv = new Canvas(reflection);
// Draw the reflection Image.
cnv.drawBitmap(reflection, 0, 0, null);
//
final Paint pnt = new Paint(Paint.ANTI_ALIAS_FLAG);
// Set the Transfer mode to be porter duff and destination in.
pnt.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint.
cnv.drawRect(0, 0, width, height, pnt);
return reflection;
}
Then, get your mirrored image like so:
final ImageView imgMirror = (ImageView) findViewById(R.id.imgMirror);
imgMirror.setImageBitmap
(
makeImageMirror
(
BitmapFactory.decodeResource(getResources(), R.drawable.head_prof)
)
);
Result:
[EDIT]
You can get the VERTICAL mirror by using this matrix: mtx.preScale(1, -1);
You can get the HORIZONTAL + VERTICAL mirror by using this matrix: mtx.preScale(-1, -1);

If you want to flip it in the code you can do something like this:
BitmapDrawable flip(BitmapDrawable d)
{
Matrix m = new Matrix();
m.preScale(-1, 1);
Bitmap src = d.getBitmap();
Bitmap dst = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, false);
dst.setDensity(DisplayMetrics.DENSITY_DEFAULT);
return new BitmapDrawable(dst);
}
You can switch the preScale values if you want to mirror on the X axis.

Try this
Assuming you are going to mirror on Y axis
private void mirrorMatrix(){
float[] mirrorY = { -1, 0, 0,
0, 1, 0,
0, 0, 1
};
matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
}
then get the mirrored bitmap and set it to the next imageButton.
private void drawMatrix()
{
Matrix matrix = new Matrix();
matrix.postConcat(matrixMirrorY);
Bitmap mirrorBitmap = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
ib.setImageBitmap(mirrorBitmap);
}
Note:
mirrorY with the Matrix.postConcat() generates a mirror image about Y axis.

Related

How to show reflection of coverflow widget in android?

hi in my project i've coverflow widget. i'm using code for that coverflow widget is in this link
this is the link i'm using
i want to implement reflection for that whole widget
thanks in advance
hi i'm using this method but not getting reflection,is any thing wrong in this? for coverflow widget
public boolean createReflectedImages() {
// The gap we want between the reflection and the original image
System.out.println(" i'm from createReflected image()");
final int reflectionGap = 4;//4
int index = 0;
for (int imageId : mImageIds)
{
Bitmap originalImage = BitmapFactory.decodeResource(
getResources(), imageId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();
//int width=100;
//int height=100;
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
//matrix.preScale(-1.0f, 1.0f);
//Bitmap mirroredBitmap = Bitmap.createBitmap(originalImage, 0, 0, originalImage.getWidth(), originalImage.getHeight(), matrix, false);
matrix.preScale(1, -1);
// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit
// reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,
null);
// Create a shader that is a linear gradient that covers the
// reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0,bitmapWithReflection.getHeight() + reflectionGap,
0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width,
bitmapWithReflection.getHeight() + reflectionGap, paint);
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
android.widget.Gallery.LayoutParams imgLayout = new CoverFlow.LayoutParams( 200, 200);
imageView.setLayoutParams(imgLayout);
imageView.setPadding(50, 100, 50, 20);
imageView.setScaleType(ScaleType.MATRIX);
mImages[index++] = imageView;
}
return true;
You can use This Coverflow in your project. It gives you option to add reflection in coverflow. I have used this in one of my previous apps
Edited -
Blog you have mentioned is using adapter which is extending BaseAdapter and is using createReflectedImages() method only
If you look into source code of link I have provided, there is CoverFlowTestingActivity is there which is using following code to setup coverflow
private void setupCoverFlow(final CoverFlow mCoverFlow, final boolean reflect) {
BaseAdapter coverImageAdapter;
if (reflect) {
coverImageAdapter = new ReflectingImageAdapter(new ResourceImageAdapter(this));
} else {
coverImageAdapter = new ResourceImageAdapter(this);
}
mCoverFlow.setAdapter(coverImageAdapter);
mCoverFlow.setSelection(2, true);
setupListeners(mCoverFlow);
}
Here you can see that if we want to reflection of images ReflectingImageAdapter in conjuction with ResourceImageAdapter which is extending AbstractCoverFlowImageAdapter.
I think this is the game changer for you

How to translate and rotate in bitmap in android?

I am trying to translate and rotate a bitmap in android ImageView. But I can't get the result. Any pointers will be helpful.
int width = mb.getWidth();
int height = mb.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();
matrix.preTranslate(width/2, height/2)
matrix.postRotate(angle);
Bitmap resizedBitmap = Bitmap.createBitmap(mb, 0, 0,
width, height, matrix, true);
imageview.setImageBitmap(resizedBitmap);

Translating using Matrix Android

I am trying to translate a image using matrix my code is
Bitmap myImg = BitmapFactory.decodeResource(getResources(), R.drawable.calednder_c);
Matrix matrix = new Matrix();
matrix.setTranslate(500,300 );
Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
matrix, true);
circle.setImageBitmap(rotated);
when i am calling my animate method nothing happening .while i wrote preRotate(angle); it rotate and it scale also but not translate why what i am missing
Thanks in advance
Here is the respective snippet from the createBitmap source code:
final boolean transformed = !m.rectStaysRect();
RectF deviceR = new RectF();
m.mapRect(deviceR, dstR);
neww = Math.round(deviceR.width());
newh = Math.round(deviceR.height());
bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
transformed || source.hasAlpha());
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(m);
paint = new Paint();
paint.setFilterBitmap(filter);
if (transformed) {
paint.setAntiAlias(true);
}
It makes the created bitmap just big enough to hold all the desired pixels from the original bitmap. This is caused by the new size and the canvas.translate call.
The net effect is that translations in the matrix are ignored.

How to change Bitmap image color in android?

I am developing an android application in which I set an image to imageview. Now programmatic I want to change the bitmap image color. Suppose my image have red color initially and now I need to change it to orange color. How can I do that? Please help.
Here is my code. I managed to change the opacity but I do not know how to change the color.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv = (ImageView) findViewById(R.id.img);
Drawable d = getResources().getDrawable(R.drawable.pic1);
Bitmap mNewBitmap = ((BitmapDrawable)d).getBitmap();
Bitmap nNewBitmap = adjustOpacity(mNewBitmap);
iv.setImageBitmap(nNewBitmap);
}
private Bitmap adjustOpacity( Bitmap bitmap ) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
dest.setPixels(pixels, 0, width, 0, 0, width, height);
return dest;
}
I tried Josip's answer but wouldn't work for me, regardless of whether the offset parameter was 1 or 0 - the drawn bitmap just appeared in original colour.
However, this did work:
// You have to copy the bitmap as any bitmaps loaded as drawables are immutable
Bitmap bm = ImageLoader.getInstance().loadImageSync("drawable://" + drawableId, o)
.copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK), PorterDuff.Mode.SRC_IN);
paint.setColorFilter(filter);
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(bm, 0, 0, paint);
Update 1
Whilst the above works well and is useful in a lot of cases, if you just want to change the main colour of an ImageView drawable, which the op did, you can just use:
imgView.setColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK));
If you need more flexibility or this doesn't give the desired effect, there's an overload that allows you to change the PorterDuff Mode until you get what you're after:
imgView.setColorFilter(ContextCompat.getColor(this, R.color.COLOR_1_DARK), PorterDuff.Mode.SRC_ATOP);
Update 2
Another good use case I've had for this lately is customizing the appearance of a Google map v2 marker icon. In order to use 2 graphics to allow (for example) small/large icons on a marker, but also a range of colours on those 2 graphics by changing the colour of them dynamically. In my case I was doing this inside a ClusterRenderer as the markers were also clustered, but this can be used with a regular map marker the same way:
#Override
protected void onBeforeClusterItemRendered(MyClusterItem item, MarkerOptions markerOptions) {
try {
int markerColor = item.getColor();
Bitmap icon;
if (item.isFeatured()) {
// We must copy the bitmap or we get an exception "Immutable bitmap passed to Canvas constructor"
icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_marker_large).copy(Bitmap.Config.ARGB_8888, true);
} else {
// We must copy the bitmap or we get an exception "Immutable bitmap passed to Canvas constructor"
icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_marker_small).copy(Bitmap.Config.ARGB_8888, true);
}
Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(ContextCompat.getColor(context, markerColor), PorterDuff.Mode.SRC_IN);
paint.setColorFilter(filter);
Canvas canvas = new Canvas(icon);
canvas.drawBitmap(icon, 0, 0, paint);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
} catch (Exception ex) {
ex.printStackTrace();
}
}
I got kind of solution.
Bitmap sourceBitmap = BitmapFactory.decodeFile(imgPath);
float[] colorTransform = {
0, 1f, 0, 0, 0,
0, 0, 0f, 0, 0,
0, 0, 0, 0f, 0,
0, 0, 0, 1f, 0};
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0f); //Remove Colour
colorMatrix.set(colorTransform); //Apply the Red
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
Paint paint = new Paint();
paint.setColorFilter(colorFilter);
Display display = getWindowManager().getDefaultDisplay();
Bitmap resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, (int)(display.getHeight() * 0.15), display.getWidth(), (int)(display.getHeight() * 0.75));
image.setImageBitmap(resultBitmap);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(resultBitmap, 0, 0, paint);
private void changeColor(){
ImageView image = (ImageView) findViewById(R.id.imageView1);
Bitmap sourceBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
changeBitmapColor(sourceBitmap, image, Color.BLUE);
}
private void changeBitmapColor(Bitmap sourceBitmap, ImageView image, int color) {
Bitmap resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0,
sourceBitmap.getWidth() - 1, sourceBitmap.getHeight() - 1);
Paint p = new Paint();
ColorFilter filter = new LightingColorFilter(color, 1);
p.setColorFilter(filter);
image.setImageBitmap(resultBitmap);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(resultBitmap, 0, 0, p);
}
It's better obtain mutable bitmap by copy, without changing size:
public static Bitmap changeBitmapColor(Bitmap sourceBitmap, int color)
{
Bitmap resultBitmap = sourceBitmap.copy(sourceBitmap.getConfig(),true);
Paint paint = new Paint();
ColorFilter filter = new LightingColorFilter(color, 1);
paint.setColorFilter(filter);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(resultBitmap, 0, 0, paint);
return resultBitmap;
}
public Bitmap replaceColor(Bitmap src,int fromColor, int targetColor) {
if(src == null) {
return null;
}
// Source image size
int width = src.getWidth();
int height = src.getHeight();
int[] pixels = new int[width * height];
//get pixels
src.getPixels(pixels, 0, width, 0, 0, width, height);
for(int x = 0; x < pixels.length; ++x) {
pixels[x] = (pixels[x] == fromColor) ? targetColor : pixels[x];
}
// create result bitmap output
Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());
//set pixels
result.setPixels(pixels, 0, width, 0, 0, width, height);
return result;
}
The simplest way to change the bitmaps color is with this method:
bitmap.eraseColor(ContextCompat.getColor(this, R.color.your_color));
If you want to overlay the ImageView with color use:
imageView.setColorFilter(ContextCompat.getColor(this, R.color.your_color));
A little off topic, but considering you only want to display in changed color here is my solution. Namely, the easiest and fast way is just applying a filter by using drawColor() method on Canvas, right after drawBitmap():
m_canvas.drawColor(Color.RED, PorterDuff.Mode.ADD);
Sources: https://developer.android.com/reference/android/graphics/PorterDuff.Mode.html
Even if bitmap is immutable, it will work.
Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(ContextCompat.getColor(context, R.color.whatColorNeed), PorterDuff.Mode.SRC_IN);
paint.setColorFilter(filter);
canvas.drawBitmap(bitmapToModify, some_x, some_y, paint);
I have solved the problem by using the below code
public void changeColor(Bitmap srcImage) {
Bitmap bmpRedscale = Bitmap.createBitmap(srcImage.getWidth(),
srcImage.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmpRedscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setRGB2YUV();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(srcImage, 0, 0, paint);
mImgEdited.setImageBitmap(bmpRedscale);
}
In Kotlin :
private fun changeBitmapColor(oldBitmap: Bitmap, newColor: Int): Bitmap {
val paint = Paint()
val filter: ColorFilter = PorterDuffColorFilter(
newColor,
PorterDuff.Mode.SRC_IN
)
paint.colorFilter = filter
val canvas = Canvas(oldBitmap)
canvas.drawBitmap(oldBitmap, 0f, 0f, paint)
return oldBitmap
}
This function PorterDuff.Mode.SRC_IN can change due to the Bitmap file, look this link https://developer.android.com/reference/android/graphics/PorterDuff.Mode

Android: Rotation of image around the center

I'm trying to rotate an image around the center. This works generally using RotateAnimation, but I want to have it a bit faster. I'm now using the SurfaceView pattern with a separate drawing thread.
This is code, which draws the bitmap correctly (depending on the outer "heading")
heading = angle in degrees,
bitmap = the bitmap,
w = width of the bitmap,
h = height of the bitmap.
Matrix m = new Matrix();
m.preRotate(heading, w/2, h/2);
m.setTranslate(50,50);
canvas.drawBitmap(bitmap, m, null);
Drawback: The image is a circle and the code above produces visible aliasing effects...
The code below is also rotating the image, but while rotating (say from 0 to 45 degrees clockwise) the center of the new image moves bottom/right. I suppose, the eccentric effect is due to the enlarged width/height of the new image ?? However, this code doesn't produce aliasing, if filter=true is set. Is there a way to use code #1 but have sort of anti-aliasing or use code #2 but getting rid of the center movement?
Matrix m = new Matrix();
m.preRotate(heading, w/2, h/2);
m.setTranslate(50,50);
Bitmap rbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, m, true);
canvas.drawBitmap(rbmp, 50, 50, null);
UPDATE: As result of the discussion in this thread the correct version of code #2 (anti-aliasing and correct rotation) would look like this (offset of 50,50 omitted):
Matrix m = new Matrix();
m.setRotate(heading, w/2, h/2);
Bitmap rbpm = Bitmap.createBitmap(bitmap, 0, 0, w, h, m, true);
canvas.drawBitmap(rbpm, (w - rbpm.getWidth())/2, (h - rbpm.getHeight())/2, null);
Thanks.
Find the center of the original image and for the new image and center using that:
Matrix minMatrix = new Matrix();
//height and width are set earlier.
Bitmap minBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas minCanvas = new Canvas(minBitmap);
int minwidth = bitmapMin.getWidth();
int minheight = bitmapMin.getHeight();
int centrex = minwidth/2;
int centrey = minheight/2;
minMatrix.setRotate(mindegrees, centrex, centrey);
Bitmap newmin = Bitmap.createBitmap(minBitmap, 0, 0, (int) minwidth, (int) minheight, minMatrix, true);
minCanvas.drawBitmap(newmin, (centrex - newmin.getWidth()/2), (centrey - newmin.getHeight()/2), null);
minCanvas.setBitmap(minBitmap);

Categories

Resources