Reputation: 516
I'm asking about how do apply Xiaolin algorithm to have a smooth corner for image in android I've wrote a algorithm that iterate over the pixels and determine wither this pixel should removed or not to have an corner for image also removing pixel by making it transparent 255 for alpha value but the corner isn't smooth and I'm reading about Xiaolin algorithm for smooth line but because I'm in intermediate java programmer I don't know how to apply this algorithm >>> can any one help me on how to apply this algorithm or suggest another algorithm and how to use it this is my code
int radius = Integer.parseInt(((EditText)MainActivity.this.findViewById(R.id.editTextRadius)).getText().toString());
int xCenter ;
int yCenter;
Bitmap mutableBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.h);
Bitmap drawaBitmap = mutableBitmap.copy(Bitmap.Config.ARGB_4444, true);
for (int i = 0; i < radius; i++) {
xCenter = radius;
yCenter = radius;
for (int j = 0; j < radius; j++) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(255, 255, 255, 255));
}
}
xCenter = radius;
yCenter = drawaBitmap.getHeight()-radius;
for (int j = drawaBitmap.getHeight()-1; j > drawaBitmap.getHeight()-radius; j--) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(255, 255, 255, 255));
}
}
}
for (int i = drawaBitmap.getWidth()-1; i > drawaBitmap.getWidth()-radius; i--) {
xCenter = drawaBitmap.getWidth() - radius;
yCenter = radius;
for (int j = 0; j < radius; j++) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2)) {
drawaBitmap.setPixel(i, j,
Color.argb(255, 255, 255, 255));
}
}
xCenter = drawaBitmap.getWidth()-radius;
yCenter = drawaBitmap.getHeight()-radius;
for (int j = drawaBitmap.getHeight()-1; j > drawaBitmap.getHeight()-radius; j--) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(255, 255, 255, 255));
}
}
}
((ImageView)this.findViewById(R.id.image)).setImageBitmap(drawaBitmap);
thanks in advance
Upvotes: 0
Views: 1728
Reputation: 24730
this is a bas stuff to start with:
int radius = 10;
Bitmap b = Bitmap.createBitmap(radius, radius, Config.ARGB_8888);
Bitmap mask = Bitmap.createBitmap(2 * radius, 2 * radius, Config.ARGB_8888);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas c;
// create mask
p.setColor(0xff000000);
c = new Canvas(mask);
c.drawCircle(radius, radius, radius, p);
// draw something on the original bitmap
// skip it if you have original bitmap drawn
c = new Canvas(b);
LinearGradient lg = new LinearGradient(0, 0, radius, radius, 0xffff0000, 0xff00ff00, TileMode.CLAMP);
p.setShader(lg);
c.drawRect(0, 0, radius, radius, p);
// end of skip
for (int x = 0; x < radius; x++) {
for (int y = 0; y < radius; y++) {
int maskPixel = mask.getPixel(x, y);
if ((maskPixel & 0xff000000) != 0xff000000) {
int bPixel = b.getPixel(x, y);
bPixel &= 0xffffff;
bPixel |= (maskPixel & 0xff000000);
b.setPixel(x, y, bPixel);
}
}
}
try {
OutputStream stream;
stream = new FileOutputStream("/sdcard/image.png");
b.compress(CompressFormat.PNG, 100, stream);
stream = new FileOutputStream("/sdcard/mask.png");
mask.compress(CompressFormat.PNG, 100, stream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Upvotes: 0
Reputation: 51571
So, I gave your code a try and its working fine for me. I did add the changes I suggested to you. Here's the xml for ImageView:
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layerType="hardware"/>
The reason why you are seeing black instead of transparent pixels could be because the layerType is not set. Corrected code:
// hardcoded this value for testing purposes
int radius = 120;
int xCenter;
int yCenter;
Bitmap mutableBitmap = BitmapFactory.decodeResource(
this.getResources(), R.drawable.h);
// ARGB_8888 // ARGB_4444 has been deprecated
Bitmap drawaBitmap = mutableBitmap.copy(Bitmap.Config.ARGB_8888, true);
for (int i = 0; i < radius; i++) {
xCenter = radius;
yCenter = radius;
for (int j = 0; j < radius; j++) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(0, 0, 0, 0));
}
}
xCenter = radius;
yCenter = drawaBitmap.getHeight()-radius;
for (int j = drawaBitmap.getHeight()-1; j > drawaBitmap.getHeight()-radius; j--) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(0, 0, 0, 0));
}
}
}
for (int i = drawaBitmap.getWidth()-1; i > drawaBitmap.getWidth()-radius; i--) {
xCenter = drawaBitmap.getWidth() - radius;
yCenter = radius;
for (int j = 0; j < radius; j++) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2)) {
drawaBitmap.setPixel(i, j,
Color.argb(0, 0, 0, 0));
}
}
xCenter = drawaBitmap.getWidth()-radius;
yCenter = drawaBitmap.getHeight()-radius;
for (int j = drawaBitmap.getHeight()-1; j > drawaBitmap.getHeight()-radius; j--) {
if (Math.pow(i - xCenter , 2) + Math.pow(j - yCenter , 2) > Math.pow(radius, 2) ) {
drawaBitmap.setPixel(i, j,
Color.argb(0, 0, 0, 0));
}
}
}
((ImageView) findViewById(R.id.image)).
setBackgroundColor(getResources().getColor(android.R.color.transparent));
((ImageView) findViewById(R.id.imageView1)).setImageBitmap(drawaBitmap);
By the way, you can also use Color.TRANSPARENT
in place of Color.argb(0, 0, 0, 0)
.
Result: Original & Processed
Upvotes: 1