If I have a view with a transparent background and I do bitmap = view.getDrawingCache();, that bitmap is unfortunately no more transparent. A black background is set in background.
I have even tried
view.setDrawingCacheBackgroundColor(Color.TRANSPARENT);
without success.
Actually this method allows to set the background color without any alpha support, Color.TRANSPARENT which is 0x00000000 is actually black if you don't care about the alpha part...
If I use Color.RED, the background is indeed very red.
Any idea to make this work? Is this a limitation of current Android API? Can I use draw() instead? but it's less performant that this view.getDrawingCache() I suppose (no cache)?
Thanks
I also get image with black background by calling getDrawingCache() method. Actually, the image has transparent background. Mistake is saving the image in jpeg format, so the gallery app shows transparent pixels in black color.
If you put it as an overlay, it'll work perfectly. There is no issue here.
Draw caching is somewhat of a relic of pre-HW-accelerated Android, so some stuff might be a bit confusing/not as well documented.
Transparency should work just fine as long as you leave out View#setDrawingCacheBackgroundColor(int) as this might cause the cache to drop down to 16 bit color space (see View#mDrawingCacheBackgroundColor).
This code
view.setDrawingCacheEnabled(true);
// wait for first layout
...
Bitmap b = view.getDrawingCache();
should give you an ARGB_8888 bitmap with transparent background. (You can also this in the Android Studio debugger by settings a breakpoint after the get call and 'View Bitmap' on the variable.
Try this code after setting the layout background color transparent in XML file
layout.setDrawingCacheEnabled(true);
Bitmap bmp = layout.getDrawingCache();
File mFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "smiley1.png");
FileOutputStream outStream;
outStream = new FileOutputStream(mFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream);
Related
I'm trying to set a color as an image to an ImageView that exists inside a custom notification. I can give it predefined colors by writing this line:
remoteViews.setImageViewResource(R.id.imageView, R.color.Green);
But i want to be able to give it hex color values, and set that as the color. I tried setting the color as the background of the ImageView, but i couldn't get access to it, and the only options i have to access the ImageView are these:
remoteViews
.setImageViewResource()
.setImageViewBitmap()
.setImageViewIcon()
.setImageViewUri()
Is there a way to pass in a color by parsing the hex value to any of these?
I think if I was able to create a bitmap and set the bitmap to the image view, it could be done, so i wrote the code bellow to create the bitmap:
int[] colors = {Color.parseColor("#64DD17"), Color.parseColor("#D32F2F")};
Bitmap bitmap = Bitmap.createBitmap(colors, 10, 10, Bitmap.Config.RGB_565);
, but i get a java.lang.ArrayIndexOutOfBoundsException. I tried with one element in the colors array too, but same error.
What is my error here?
The int[] is your image; so you create an image 2px wide, since that's the length of your array. However, you call createBitmap and specify that the image is in fact 10pxx10px; this is why the ArrayIndexOutOfBoundsException is thrown, as Android starts looking for pixels that aren't there.
Using Bitmap bitmap = Bitmap.createBitmap(colors, 2, 1, Bitmap.Config.RGB_565); would solve this problem, albeit generate a very tiny image!
Simple solution: generate png images(or use svg) to put inside the image view, instead of the color you want.
but, if u want to use that approach, you can create a colored bitmap using something like that:
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
image.eraseColor(android.graphics.Color.GREEN);
I have an app with two views - one on top of another. On the top one I use a Bitmap (ARGB_8888) loaded from a PNG resource and I play with its alpha channel to make some parts of it disappear so the one below becomes visible. All works fine if the source image has at least a single transparent pixel to start with. But if the source PNG has no transparent pixels then changing it alpha to 0 makes the pixel I changed black, not transparent.
Any ideas what could be done to fix it? anything like:
aaptOptions {
cruncherEnabled = false
}
but another option?
Currently I modify the source images before compiling by making a tiny area of it "semi-transparent" but would like to avoid that.
Ok. Finally got it.
I had to add one line. Instead of:
mBitmap = BitmapFactory.decodeResource(getResources(), getResourceID()).copy(Bitmap.Config.ARGB_8888, true);
I am now using:
mBitmap = BitmapFactory.decodeResource(getResources(), getResourceID()).copy(Bitmap.Config.ARGB_8888, true);
mBitmap.setHasAlpha(true);
and there is no need to add a transparent pixel on the source image!
So I have an imageview which I use setImageBitmap(pic) about about 30fps as a form of video stream, and the imageview image (not the rest of the screen) flashes black or disappears every few seconds. Is there a special setting to the imageview I need to add or disable in order to make it not go blank or flicker? I tried setting the imageview image, the layout's background image, VideoView, and all of them flicker black every few seconds while I update the background image. Any fix?
The image is about 320px wide and im not sure how tall, less than 320 tho.
Code doesn't really seem necessary, but this is all im doing ('imageStream' is the ImageView):
RunOnUiThread (() => StreamActivity.imageStream.SetImageBitmap(pic));
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageViewStream"
android:focusable="false"
android:focusableInTouchMode="false"
android:soundEffectsEnabled="false"
android:clickable="false"
android:longClickable="false"
android:hapticFeedbackEnabled="false"
android:adjustViewBounds="true"
android:cropToPadding="true" />
EDIT: I tried setting to software layer type, hardware layer type, and setting background color to Color.Argb(1, 0, 0, 0)
None of that worked.
EDIT: I seem to have fixed it by setting the application to run as hardware accelerated, and also the imageview and layout as hardware accelerated.
Then i changed my image setting code to
Bitmap tempBitmap = Bitmap.CreateBitmap(pic.Width, pic.Height, Bitmap.Config.Rgb565);
Canvas tempCanvas = new Canvas(tempBitmap); // then draw to the Canvas.
tempCanvas.DrawBitmap(pic, 0, 0, null);
RunOnUiThread (() => StreamActivity.imageStream.SetImageDrawable(new BitmapDrawable(tempBitmap)));
i thnk its because of RunOnUiThread.
if just want to change image in imageview jst use
ImageView.setBackgroundResource(R.drawable.thumbs_down);
I seem to have fixed it by setting the application to run as hardware accelerated, and also the imageview and layout as hardware accelerated.
Then i changed my image setting code to
Bitmap tempBitmap = Bitmap.CreateBitmap(pic.Width, pic.Height, Bitmap.Config.Rgb565);
Canvas tempCanvas = new Canvas(tempBitmap); // then draw to the Canvas.
tempCanvas.DrawBitmap(pic, 0, 0, null);
RunOnUiThread (() => StreamActivity.imageStream.SetImageDrawable(new BitmapDrawable(tempBitmap)));
and in my OnCreate()
imageStream.SetLayerType(LayerType.Hardware, null);
frameLayout1.SetLayerType(LayerType.Hardware, null);
and in my androidmanifest:
<application
android:label="MyName"
android:hardwareAccelerated="true"/>
I got around this by creating a BitmapDrawable from the bitmap OFF the UI thread, then calling SetImageDrawable ON the UI thread, then disposing of the BitmapDrawable.
I don't know why this works but I guess there is some overhead taken care of when creating the drawable that lightens the load on the draw routine.
I'm using Xamarin but you get the idea (the eventArgs.Frame is an Android Bitmap):
_stream.NewFrame += (object sender, NewFrameEventArgs eventArgs) =>
{
var bd = new BitmapDrawable(eventArgs.Frame);
(Context as Activity).RunOnUiThread(() =>
{
SetImageDrawable(bd);
bd.Dispose();
});
};
I do some tests on drawing text on path. I made a background picture by setting bitmap to the canvas. Then, I draw text on a path to canvas, rotated by matrix. I have to shorten the code, I will only post the important part because it is too long. This images shown below are cropped with gimp, so don´t be irritated by the different sizes. My Rect, Path and Matrix objects:
RectF drawTextOval;
Path drawTextPath;
Matrix mDrawnMatrix;
Now, this is what I am doin to draw text on circle path:
drawTextOval.set(drawTextPosX - drawTextArc, drawTextPosY
- drawTextArc, drawTextPosX + drawTextArc, drawTextPosY
+ drawTextArc);
drawTextPath.addArc(drawTextOval, 0, 360);
drawTextPath.computeBounds(drawTextOval, true);
mDrawnMatrix.postRotate(drawTextArcStart,
(drawTextOval.right + drawTextOval.left) / 2,
(drawTextOval.bottom + drawTextOval.top) / 2);
drawTextPath.transform(mDrawnMatrix);
patternCanvas.drawTextOnPath(drawText, drawTextPath, 0, 0,
mFixedTextPaint);
Until this point, everything looks fine:
But after saving the whole screen, the rotated text looks warped at the saved .png image. All the other components looking good. I made some other drawings with text, linear or angular, all this works. Even some .png bitmaps drawing to canvas and the background image...all are looking normally. But the on circle path drawn text looks like this:
I don´t do any scaling on the bitmap, just saving the canvas image with:
FileOutputStream fos = new FileOutputStream(saveFile);
this.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = this.getDrawingCache();
bitmap.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Why does the text look warped? Does anyone see my mistake? Thanks in advance...
EDIT
I tried some stuff and find out that setting any density to false or disable hardware acceleration in Manifest will show the effect at runtime before saving. That suggests to me, that when saving bitmap with getDrawingCache(), the scaling is disabled at this time. But why?
The last thing I found out, that the lower the curvature the lower is the text scaling. If the text is just a little bit curved, it seems good.
I would try setting the
this.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
before drawing to screen, since lower quality might imply a simpler transformation of the text. This is just guessing of course. Currently your only setting the high quality before writing to disk. Or simply remove it from the write to disk method to check if it affect the way the text is drawn.
I am a beginner at android, but hoping to release an app shortly.
My problem is, that I would like to have a seekbar with colored areas according to user/database input.
I have tried some things with ShapeDrawable but I am comletely lost and the only result I got was making the seekbar completely black.
I am not allowed to post images, but here is link to a photoshopped image of what I am looking for:
http://www.burninglobster.com/device-2012-10-29-155734ps.png
You can manually draw to bitmap via canvas according to your input data.
Bitmap.Config bmpConfig = Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(seekbar.getWidth(), seekbar.getHeight(), bmpConfig);
Canvas canvas = new Canvas(this.bmp);
canvas.drawRect(...); // draw whatever you need
seekbar.setBackgroundDrawable(new BitmapDrawable(bmp));
Hope this helps.