Small SVG imageview looks blurry or "curvy" - android

I have generated a vector asset (based on an own svg file) via Android Studio.
The layout code of my image view:
<ImageView
android:id="#+id/iv_drink"
android:layout_width="21dp"
android:layout_height="30dp"
android:layout_marginStart="24dp"
android:layout_marginBottom="4dp"
android:scaleType="fitXY"
app:srcCompat="#drawable/ic_smoothie_icon" />
The issue is, that this small version of the image looks "curvy" or blurry. Below is a screenshot with increased size (so you can see the cury edges of the images).
My compileSdkVersion is 28 and minSdkVersion is 21.
I tried to solve this with the use of the following:
imageview: android:scaleType="fitXY"
imageview: app:srcCompat instead of app:src
build.gradle: vectorDrawables.useSupportLibrary = true
tried different sizes within the asset xml
What could cause this issue?
EDIT:
This is the content of the svg (image is based on a file from freepik.com):
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-318 422.4 85.6 122.6" style="enable-background:new -318 422.4 85.6 122.6;" xml:space="preserve">
<g>
<path d="M-232.4,445l-6.1,100h-49.9l-6.1-100h20.7c-0.6-5.7-1-9.9-1.1-11.7c-0.3-4.8-1.6-6.1-2.1-6.5c-0.4-0.3-0.9-0.6-0.9-0.6
l-0.3-0.2H-318v-3.1c0,0,14.6-0.5,26.9-0.5c8.4,0,15.8,0.2,16.8,1c2.3,1.8,3.7,4.8,4,9.8c0.1,1.8,0.5,6.1,1.1,11.8L-232.4,445
L-232.4,445z"/>
</g>
</svg>
Vector xml:
<vector android:height="12.3dp" android:viewportHeight="123"
android:viewportWidth="86" android:width="8.6dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:pathData="M85.6,22.6l-6.1,100h-49.9l-6.1,-100h20.7c-0.6,-5.7 -1,-9.9 -1.1,-11.7c-0.3,-4.8 -1.6,-6.1 -2.1,-6.5c-0.4,-0.3 -0.9,-0.6 -0.9,-0.6l-0.3,-0.2L0,3.6v-3.1c0,0 14.6,-0.5 26.9,-0.5c8.4,0 15.8,0.2 16.8,1c2.3,1.8 3.7,4.8 4,9.8c0.1,1.8 0.5,6.1 1.1,11.8L85.6,22.6L85.6,22.6z"/>
</vector>

Here i have made your vector using more scale friendly dimension and angles and remember that we can't draw half a pixel there will be anti-aliasing involved but we can mitigate by tweaking out shapes. when working with vector and animated vectors you can use shape-shifter to edit your path and make it android friendly or even animate it.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9,21L7,6L12,6C12,6,12.013,4.071,12,3.5C,11.987,2.929,12.081,3,11.5,3,L4,3L4,2C4,2,11.505,2.006,12,2,C12.26,2.015,12.506,2.125,12.691,2.309,C12.875,2.494,12.985,2.74,13,3L13,6L18,6L16,21Z"/>
</vector>

I think you're running up against the limits of how smooth a sloped line can look, at low resolution. The blurriness is due to anti-aliasing, which is an attempt to smooth out the jagged edge that would result from using only black or white pixels.
If you want to reduce the "curvy" effect, you can try changing the slope of the sides of the cup. Since your cup sides are almost vertical, there are a few large "steps" on each side, so the curviness is more noticeable. Make them completely vertical, or more slanted. A vertical line will have no steps. A more slanted line will have more steps, but smaller ones, so they should be less bumpy.

I think your problem is because of scaleType. Of course your vector width and height have problem too. Please try this:
<ImageView
android:id="#+id/iv_drink"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginBottom="4dp"
app:srcCompat="#drawable/ic_smoothie_icon" />

On my side moving to ConstraintLayout instead of using LinearLayout or FrameLayout removes the blurry quality on vector drawable.

Related

Image doesn't resized even if size is defined in XML (Android Studio)

I want to make button with image like this:
This button has image above its text and image is resized from 512x512.
When I searched google, there were some methods to achive this. But I thought putting Text and Image inside LinearLayout and register onClick doesn't look nice so I decided to use drawableTop instead.
<Button
android:id="#+id/btn_gps"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:drawableTop="#drawable/main_icon_gps"
android:padding="20dp"
android:text="#string/main_btn_gps"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="#+id/guideline_h60"
app:layout_constraintEnd_toEndOf="#+id/guideline_v50"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline_h40" />
Original image is 512x512 so I made another XML file(main_icon_gps) inside drawable directory.
<!-- #drawable/main_icon_gps -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#drawable/drawable_gps"
android:width="64dp"
android:height="64dp"
/>
</layer-list >
It looked nice when inspecting in Android Studio preview but when I launched the app in AVD, image resize doesn't work properly.
To sum up, I tried to set image size with android:width and android:height inside separate XML drawable file and it worked nicely in Android Studio preview. But Android doesn't respect width and height that I defined in XML drawable file. How to make Android respect the width and height that I've defined at XML?
I have to use same image as different size so resizing actual image or have multiple image don't seem to be best idea.
Nesting things inside LinearLayout isn't good idea to me but if I have to achive what I want to make, then I will use that method. Before that, I want to fix the problem that image doesn't get resized.
You can use MaterialButton and iconSize attribute.
or use VectorDrawable instead of png image, in this way you can set width and height in your xml file, like this:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#fff"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

How to make the vector logo smaller and fit the icon

I have made a logo ic_launcher.xml for my android application using "New Vector Asset" and copying the vector paths from the asset into the ic_launcher_background.xml
The logo that resulted is too big and cropped. In android I see only the central part, with sides, top and bottom cut off.
I would like for the vector to be smaller so it would be visible whole in the logo.
I have tried changing these values:
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
This resulted in the logo either being even bigger with more cropped out, or smaller, but not centered.
These are the paths for the vector:
<path
android:name="light_triangle"
android:fillColor="#color/colorAccent"
android:pathData="M 0,0 L 100,0 0,100 z" />
<path
android:fillColor="#color/colorPrimary"
android:pathData="M5,13.18v4L12,21l7,-3.82v-4L12,17l-7,-3.82zM12,3L1,9l11,6 9,-4.91V17h2V9L12,3z"/>
I would like for the logo to be smaller and centered. Can I somehow move the vector after making it smaller by changing height and width, or do I have to make new vector asset that is somehow smaller and centered?
UPDATE:
I have found what has to be done. I put the vectors inside a group like this:
<group android:scaleY="0.7" android:scaleX="0.7" android:pivotY="10" android:pivotX="10">
<path
android:fillColor="#color/colorPrimary"
android:pathData="M5,13.18v4L12,21l7,-3.82v-4L12,17l-7,-3.82zM12,3L1,9l11,6 9,-4.91V17h2V9L12,3z"/>
</group>
Use vector image directly in AndroidManifest.xml file
android:icon="#drawable/work_mode"
Change the android:width and android:height values without changing the android:viewportWidth and android:viewportHeight. In this way :
android:width="16dp"
android:height="16dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
I have found what has to be done. I put the vectors inside a group like this:
<group android:scaleY="0.7" android:scaleX="0.7" android:pivotY="10" android:pivotX="10">
<path
android:fillColor="#color/colorPrimary"
android:pathData="M5,13.18v4L12,21l7,-3.82v-4L12,17l-7,-3.82zM12,3L1,9l11,6 9,-4.91V17h2V9L12,3z"/>
</group>

Drawable vector resized incorrectly

I created a logo in Adobe Illustrator, exported it as SVG and imported it to Android Studio through Asset Studio.
When the vector is painted big, it is resized correctly (image 1), but when it's small (image 2), something goes wrong.
Both are ImageView, the second one is inside the Toolbar.
Here is the vector:
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="128.0"
android:viewportWidth="128.0"
android:width="24dp" >
<path android:fillColor="#7c7c7c" android:pathData="M64,64m-64,0a64,64 0,1 1,128 0a64,64 0,1 1,-128 0"/>
<path android:fillColor="#0b5c5d" android:pathData="M63.91,63.91m-57.6,0a57.6,57.6 0,1 1,115.2 0a57.6,57.6 0,1 1,-115.2 0"/>
<path android:fillColor="#fff" android:pathData="M77.31,16.23s-25.13,0.69 -40.7,5.59c-24.64,8.76 -23.73,45.63 -6.94,56C35.88,82.05 61.59,80 61.59,80l5.32,-15.27s-17.23,5.49 -28.67,-1.47C34.3,61.12 31.87,44 40,36.94S75.16,33.3 75.16,33.3Z"/>
<path android:fillColor="#fff" android:pathData="M51.87,43c15.77,2.66 54.59,-3.2 55.95,-3.53 1.56,-0.39 -23.14,37.71 -29,51.92A73.06,73.06 0,0 0,105.28 90s-4.91,12.15 -4.88,16.64c-7.3,-1.58 -41.33,-4.25 -50.87,-3 4.3,-4.55 27.39,-38.13 31.4,-47 -12.16,0.39 -17.8,-0.47 -33.51,0.06C49.18,53.29 51.6,49.79 51.87,43Z"/>
</vector>
I have no idea what is happening.
When exporting the SVG from Adobe Illustrator I tried changing the decimal count, resizing the document to be bigger and smaller and other settings in the dialog.
Hello please check my below code i already check this with pragmatically and i got correct output.
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/black_overlay">
<ImageView
android:id="#+id/button"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
app:srcCompat="#drawable/your_drawable" />
</android.support.v7.widget.Toolbar>
If you are using other layout for toolbar then include those toolbar into those between then it's fine.
If you have still problem after this try then please put your xml code so i can check and solving your problem.
According to your drawable xml:
You have to create copy of this drawable to use in toolbar, for this toolbar you have to reduce the view port size here with toolbar height and weidth.
android:viewportHeight="YOUR TOOLBAR HEIGHT"
android:viewportWidth="YOUR TOOLBAR HEIGHT (to make it square)"

Android: Vector has blur on android 4.4

There TextView and I want him to do VectorDrawable background. I do vector.xml
<vector android:height="24dp" android:viewportHeight="114.0"
android:viewportWidth="494.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF"
android:pathData="M12,86.61L2.19,76.51L12,67.18L12,8C12,3.58 15.59,0 20.01,0L483.99,0C488.42,0 492,3.58 492,8L492,102C492,106.42 488.41,110 483.99,110L20.01,110C15.58,110 12,106.42 12,102L12,86.61Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>
and this VectorDrawable on android 4.4 has a fuzzy edge (not clear), but on android 5.0+ everything looks good (as needed).
Help solve the problem with android 4.4
Use this when using ImageView
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/ic_add" /> <- This may help
Vector Drawables are also supported in cases like TextView's drawableLeft property
(with custom Textview to handle vector for PreLollipop version).

Android Vector Asset Studio gives extra padding to some vector images

I'm trying to import some icons from Material Vector package in Vector Asset Studio.
But they come with padding.
Why does this happen and how can I remove it?
This is inconvenient because this means if I want my icon to be 17dp x 17dp in XML, then I need to set it more than 17x17 to make up for the padding.
Android Vector Asset
You are able to scale a vector that will remove additional space. This is possible using group tag. Just modify your vector xml file.
From
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
</vector>
to
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<group
android:pivotX="12"
android:pivotY="12"
android:scaleX="1.5"
android:scaleY="1.5">
<path
android:fillColor="#FF000000"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
</group>
</vector>
As result
You can adjust for any "implicit" padding that may be contained within a VectorDrawables source image (.SVG, .PSD) by setting your ImageViews android:scaleType to the appropriate value so it can handle the padding that is secretly contained in the VectorDrawables source image. You will also need to set android:adjustViewBounds="true".
For example, lets say your VectorDrawable has some really annoying padding at the start of the image when you display it. You have no idea why it's there because you aren't setting any android:paddingStart on the ImageView... what you need to do is set the ImageViews android:scaleType to fitStart and android:adjustViewBounds to true.
tl;dr
Adjust your ImageViews android:scaleType to handle any "implicit" padding that is contained in your VectorDrawables source file (.SVG, .PSD). Also set android:adjustViewBounds="true".
Quick Example:
<ImageView android:id="#+id/vectorDrawable_imageView"
<!--Other ImageView settings-->
android:adjustViewBounds="true"
android:scaleType="fitStart"
app:srcCompat="#drawable/vector_with_implicit_padding_at_start"
/>
This will remove that annoying "implicit" padding that was at the start of your VectorDrawable.
Note: Adjust the android:scaleType according to your rendering needs.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="28"
android:viewportHeight="28">
<group
android:translateX="2"
android:translateY="2">
<path
android:fillColor="#8A333333"
android:pathData="M13.12,2.06L7.58,7.6c-0.37,0.37 -0.58,0.88 -0.58,1.41V19c0,1.1 0.9,2 2,2h9c0.8,0 1.52,-0.48 1.84,-1.21l3.26,-7.61C23.94,10.2 22.49,8 20.34,8h-5.65l0.95,-4.58c0.1,-0.5 -0.05,-1.01 -0.41,-1.37 -0.59,-0.58 -1.53,-0.58 -2.11,0.01zM3,21c1.1,0 2,-0.9 2,-2v-8c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2v8c0,1.1 0.9,2 2,2z" />
</group>
</vector>
android:viewportWidth += android:translateX * 2 (padding start / end)
android:viewportHeight += android:translateY * 2 (padding top / bottom)
This padding is on some icons so that all of the icons can align properly. For example, if in that dialog, you pick ic_3d_rotation_24dp, you'll see the icon goes all the way to the edge of the bounds.
PS if you aim to have all your sizes be a multiple of 8dp, things will line up nicely and look great.

Categories

Resources