Android Studio

How To Add an Image To Android Studio Layout

How To Add an Image To Android Studio Layout

Before any layout file or line of code can reference an image, that file has to sit inside the correct resource folder. That’s the real starting point for how to add an image to Android Studio, and it trips up a surprising number of people who assume dragging a PNG into the project window is enough on its own.

Files get sorted by screen density once they land in the res directory. Resource Manager handles that sorting, and AAPT2 compiles the result into the build afterward.

Resource Manager itself isn’t old. It showed up in version 3.4 of Android Studio, released in April 2019, according to Android Police’s 2019 coverage of the update.

What Is a Drawable Resource in Android Studio?

Drop a PNG anywhere outside the res directory and Android Studio treats it as nothing more than a file sitting in your project, invisible to any layout or class that tries to call it by name. The moment that same file moves into a drawable folder and picks up a generated resource id, it becomes something the compiler actually recognizes.

That folder sits inside the res directory, right next to the mipmap folder reserved for launcher icons.

Android Studio, the IDE Google built on top of the IntelliJ platform, doesn’t really distinguish between a PNG, a WebP file, or a converted SVG once any of them land there. They all get treated the same way from that point on.

The actual compiling runs through the wider set of command line and IDE tools bundled with the Android SDK, not through Android Studio working alone.

So the difference between a raw image file and a drawable resource comes down to one thing: the generated id. That’s what lets you call an image with a single line of code instead of hardcoding a file path.

Drawable Resource Directory Structure and Density Qualifiers

Android Studio splits the drawable folder into density-specific subfolders, one per screen density bucket, so the system can hand each device the version sized for its own pixels.

The naming follows the density scale pretty directly: drawable-mdpi, drawable-hdpi, drawable-xhdpi, drawable-xxhdpi, drawable-xxxhdpi, and a density-independent drawable-nodpi for anything that shouldn’t be scaled at all, ever.

Why does Android dominate the mobile world?

Uncover Android development statistics: market share dominance, developer opportunities, ecosystem growth, and mobile innovation trends.

Explore Android Insights →

Android’s official developer documentation spells out the baseline dpi behind each bucket.

  • mdpi, about 160 dpi, the 1x baseline where 1 dp equals 1 px
  • hdpi, about 240 dpi
  • xhdpi, about 320 dpi
  • xxhdpi, about 480 dpi
  • xxxhdpi, about 640 dpi

The scaling ratio across those six primary densities is fixed at 3:4:6:8:12:16, per Android’s developer documentation. A 48×48 px icon at mdpi turns into 72×72 at hdpi, and 96×96 at xhdpi.

Every one of those density folders lives inside the same res directory, which is really just a structured corner of your project’s codebase.

File Naming Rules for Drawable Resources

A drawable file name becomes part of its resource id, which is exactly why Android Studio enforces a fairly narrow naming convention before it agrees to compile anything.

  • Lowercase letters only, no capital letters anywhere in the name
  • Underscores in place of spaces or hyphens
  • Must start with a letter, never a number
  • Limited to letters, digits and underscores, no other punctuation

Break one of those rules and Gradle sync fails with a resource compilation error before the app ever reaches the emulator. It’s one of those errors that looks scarier than it actually is once you know what caused it.

New to ADB or just need a quick reference? Device management, file transfers, and shell commands - including adb devices, adb push/pull, and logcat - is on one page in the ADB Commands Cheat Sheet.

Supported Image File Formats for Drawables

PNG, JPG and WebP cover the raster side of things in Android Studio. SVG and PSD files get converted too, through Vector Asset Studio, which turns them into VectorDrawable XML on import rather than keeping them as-is.

GIF and BMP don’t count as standard drawable formats on their own. Android Studio can convert a BMP file, or a static GIF, into WebP once it’s already sitting inside the project, but neither format goes in directly.

FormatTypeTypical UseFile Size
PNGRasterIcons, images needing transparencyLarger, lossless
WebPRasterPhotos, general imagerySmaller than PNG or JPG
JPGRasterPhotographic backgroundsNo transparency support
SVGVector sourceSimple icons, logosConverted to XML, scales freely

Android’s official developer documentation puts WebP lossless files at roughly 26% smaller than PNG, with lossy WebP running 25 to 34% smaller than a comparable JPG at similar quality. That’s not a trivial difference once you’re shipping dozens of images.

Native VectorDrawable support arrived in Android 5.0, API level 21, per the same documentation. That’s also why Vector Asset Studio still bothers generating a PNG fallback for projects with an older minimum SDK, older devices just can’t render the XML version.

Which Method Should Be Used to Import an Image into Android Studio

Resource Manager works best for most projects. It previews the image before import and assigns density qualifiers on its own, and when you’re bringing in a whole batch of files at once, it handles the entire set in one pass instead of making you repeat the process file by file.

Drag and drop, or copy paste, work fine too, but only for a single quick image. Neither one prompts you to rename a file or set a density qualifier the way Resource Manager does, which is exactly how a lot of naming-convention errors sneak in.

MethodBest ForSteps RequiredLimitation
Resource ManagerMultiple images, bulk importOpen panel, add, confirm densityExtra clicks for one file
Drag and dropA single quick imageDrag file onto Project viewNo density prompt
Copy pasteFiles already on clipboardCopy, paste into drawable folderEasy to skip naming rules
Image Asset StudioApp icons specificallyLaunch wizard, pick layersBuilt for icons, not content images

Using Android Studio day to day makes this choice pretty easy in practice, since Project view and Resource Manager sit right next to each other in the same window.

Vector Asset Studio deserves a mention here too. It ships with a built-in library of icons that follow Material Design principles, so a project needing a standard icon rarely needs to go find an external image file at all.

How to Add an Image to the Drawable Folder Step by Step

YouTube player

Adding an image through Resource Manager starts with opening the panel and ends with the file showing up under res/drawable. It’s not complicated, but it’s easy to rush past the confirmation step and end up in the wrong density folder.

  1. Open View, then Tool Windows, then Resource Manager, or click the Resource Manager tab next to Project view.
  2. Click the plus icon and choose Import Drawables from the menu.
  3. Select the image file or files in the file browser and click Open.
  4. Confirm the resource name and, if prompted, set the density qualifier, or choose No Density for an image that should never scale.
  5. Click Import, then switch to Project view and confirm the file sits under app, res, drawable.

Skipping that last step is a common mistake. The import can succeed silently while the file lands in the wrong density folder, and you won’t necessarily notice until the image looks off on a real device.

Once the import finishes, run a Gradle sync so the build system actually picks up the new resource and generates its id.

Without that sync, referencing the image from code or XML throws an unresolved reference error, even though the file is sitting right there in the project, which is confusing the first time it happens to you.

How Android Studio Generates the Resource ID for an Image

Android Studio itself doesn’t generate the resource id. That job belongs to AAPT2, the Android Asset Packaging Tool, and it happens during the Gradle build, not inside the editor.

AAPT2 parses every file in res, indexes it, compiles it into a binary format, and writes a matching entry into the auto-generated R class.

Android Gradle Plugin 3.0.0 and higher turns AAPT2 on by default, according to Android’s developer documentation, so most projects never call the compiler directly or even think about it.

That R class entry is what makes @drawable/my\_image or R.drawable.my\_image valid the moment Gradle sync finishes.

  • Rename the file, and the old resource id disappears until the project rebuilds
  • Delete the file, and every reference to it turns into a build error
  • Skip Gradle sync, and the new id simply doesn’t exist yet

Renaming a drawable is effectively a small code refactoring job, since Android Studio has to go update every reference to that resource across the project.

How to Reference a Drawable in Layouts and Code

Every reference to a drawable has to match its file name exactly, since that name is the resource id the R class generated in the first place.

How you actually write that reference depends on where it’s used: XML, Kotlin, Java, or a Compose function.

Referencing a Drawable in XML

An ImageView in a layout file points to a drawable through the android:src attribute.

The syntax is short: android:src=”@drawable/my\_image”, with no file extension included.

  • Works inside any layout XML file, ConstraintLayout included
  • The Layout Editor preview updates immediately once the attribute is set
  • A typo in the name shows up as a red, unresolved reference in the editor

Referencing a Drawable in Kotlin or Java

Calling a drawable from code runs through ContextCompat rather than pointing at the file directly.

  • ContextCompat.getDrawable(context, R.drawable.my\_image) returns a Drawable object, and pulls in the AndroidX Core dependency (androidx.core:core) rather than appcompat specifically
  • imageView.setImageResource(R.drawable.my\_image) sets it directly on a view, and needs no extra dependency at all, since it’s a native ImageView method built into the Android framework

The syntax differs a bit between Kotlin and Java, but the resource id and the R class behind it stay identical either way.

Referencing a Drawable in Jetpack Compose

Compose skips ImageView and ContextCompat entirely.

Compose does this in one line. An Image composable takes painterResource(id = R.drawable.my\_image) as its painter argument.

  • No context object needs to be passed in manually
  • Works for both raster drawables and converted vector XML files

Vector Versus Raster Images: Which to Use

One XML file is all a vector drawable needs, and it scales cleanly to whatever screen density shows up. Raster images don’t get that convenience. Every density bucket needs its own separate bitmap, mdpi through xxxhdpi, and that adds up.

Vector Asset Studio is what produces the first kind. Image Asset Studio, or a plain drag and drop, produces the second.

Vector drawables save real ground in a few ways. One XML file replaces five density-specific bitmaps, and resizing happens without any blur or pixelation showing up at any density. The APK stays smaller too, since nothing needs duplicating per bucket.

They’re not free, though. Vector drawables cost more CPU on the first draw than an equivalent bitmap, and they don’t handle photographic detail or complex gradients particularly well. There’s also a practical ceiling. Android’s own documentation caps a vector image at 200 x 200 dp before draw time starts climbing noticeably.

Raster holds its own in certain spots too. It handles photos and detailed artwork without any real size ceiling, and it draws instantly once decoded since there’s no per-frame path calculation involved.

The catch with raster is weight. You need a separate file for mdpi through xxxhdpi just to stay sharp, and that adds up to noticeable APK bloat once a project is carrying more than a handful of images across five density folders.

A simple icon almost always belongs in Vector Asset Studio. A photo, or a busy illustration, belongs in the drawable folder as WebP or PNG instead.

How to Add an App Icon or Adaptive Icon in Android Studio

An app icon needs Image Asset Studio, not the Resource Manager import flow you’d use for an ordinary content image.

The wizard walks through foreground and background layers before it writes anything to disk.

  1. Right-click the res folder, then choose New, Image Asset.
  2. Select Launcher Icons (Adaptive and Legacy) as the icon type.
  3. Pick a foreground layer, an image, text, or a clip art shape from the built-in library.
  4. Pick a background layer, usually a solid color or a simple pattern.
  5. Click Next, then Finish to generate every density variant automatically.

Android’s own developer documentation sizes every adaptive icon layer at 108 x 108 dp, with a 66 x 66 dp safe zone that stays clear of any launcher mask.

Adaptive icons have been part of the platform since Android 8.0, API level 26. Older launchers just fall back to the legacy square or round icon instead, no crash, no error, just a plainer icon.

Legacy launcher icons land in the mipmap folder, not drawable, because mipmap directories survive density-specific APK splits that would otherwise strip out an icon a device actually needs.

The generated XML also updates the AndroidManifest reference automatically, so android:icon keeps pointing at the right resource without any manual edit.

How to Load Images with Glide, Picasso, or Coil Instead of a Static Drawable

A drawable resource works fine for anything bundled with the app at build time. It breaks down the moment an image depends on user data or a server response.

Glide, Picasso and Coil all load a remote or dynamic image into an ImageView, but they’re not really interchangeable. Each one has settled into a different niche.

LibraryLanguage FitStatusBest For
GlideKotlin or JavaActively maintainedComplex caching, GIFs, transformations
PicassoKotlin or JavaDeprecatedLegacy projects only
CoilKotlin-firstActively maintainedCompose projects, lightweight apps

Square’s own repository for Picasso now marks the library deprecated, and it tells teams to migrate to Coil, especially for anything built with Compose UI.

Coil’s own documentation puts its footprint at roughly 2,000 added methods, comparable to Picasso and noticeably lighter than Glide.

A loading library tends to win over a bundled drawable in a couple of common scenarios: profile pictures and other content pulled from an API, or anything that changes without shipping a new build. Big photo feeds are their own case too, since lazy loading and disk caching actually start to matter once the list runs long.

None of the three replaces the drawable folder for icons, backgrounds, or anything shipped inside the APK itself. They solve a different problem.

Why an Image Fails to Show Up After Being Added

Most missing-image bugs have nothing to do with the image file itself being broken. The cause is almost always somewhere else entirely.

  • A stale build shows old output, Android Studio hasn’t caught up with the newest resource id in the R class it’s reading from
  • Case sensitivity trips people up too, a resource name that works fine on Windows or macOS can fail on a Linux build machine, since Windows and macOS default to case-insensitive file systems while Linux treats uppercase and lowercase as different names entirely
  • The wrong density folder causes trouble in a quieter way, an image sitting in drawable-xxxhdpi displays at a fraction of its intended size on an mdpi device, because the system assumes that folder holds the largest version
  • A duplicate resource name, the same name used twice within one resource type, such as two files both named the same inside drawable, triggers a build error, since AAPT2 rejects two resources that resolve to the same name, type and qualifier. The same name split between drawable and mipmap doesn’t collide though, those are different resource types with separate R class entries

A quick check in the Android Studio emulator usually confirms whether the problem is the build itself or just a stuck preview.

If the R class genuinely lacks the entry, Build, then Clean Project, then Rebuild Project forces AAPT2 to reprocess every resource from scratch.

An ImageView with no visible height, set to wrap\_content inside an otherwise empty container, can also look exactly like a missing image when the drawable is actually loading correctly. That one’s caught more than a few people off guard.

When Adding an Image to the Drawable Folder Does Not Apply

The drawable folder is built for assets that ship with the app and don’t change until the next release. That assumption breaks down in a handful of common situations.

Large media files are the first problem. A photo gallery, video thumbnails, or anything running into dozens of megabytes bloats the build you ship rather than helping it in any way.

User-uploaded or frequently changing images are another. A profile photo, a product image pulled from a catalog, or anything tied to a database record just doesn’t belong compiled into res at all.

Animated formats don’t fit either, and this one trips people up more than you’d expect. The drawable pipeline only compiles static images and VectorDrawable XML. A GIF or an animated WebP needs a dedicated player, not android:src.

Then there’s APK size. Google Play enforces a hard cap on what a single APK can weigh, and every bundled drawable variant across five density buckets counts against that limit.

Choosing between an APK or AAB output changes this calculation, since an Android App Bundle can strip unused density variants per device instead of shipping every one of them to every user.

In every one of these cases, the right move is remote loading through a library, not a bigger drawable folder.

FAQ on How To Add Image To Android Studio

What is the difference between the drawable folder and the mipmap folder?

Both folders live inside the res directory, but they hold different resource types.

The drawable folder stores general images and vector drawables, while mipmap is reserved for launcher icons that survive density-specific APK splits.

How many density versions of an image does a project actually need?

Most projects don’t need all five density buckets filled for every single image.

Shipping xxhdpi and xxxhdpi covers the vast majority of active devices, and a vector drawable removes the question entirely for simple icons anyway.

What is the maximum recommended size for a launcher icon image?

Adaptive icon layers inside the app stay at 108 x 108 dp, already covered above.

Google Play’s store listing icon is a separate thing entirely. It’s a fixed 512 x 512 px, 32-bit PNG uploaded through Play Console.

How is an SVG file converted into a Vector Drawable?

Vector Asset Studio reads the SVG’s path data and rebuilds it as VectorDrawable XML, not as a bitmap.

It flags any unsupported SVG feature right away, since the W3C’s SVG standard covers a lot more ground than the vector drawable format can actually render.

Why does Android Studio report a duplicate resource error for an image?

AAPT2 rejects two resources that resolve to the same name inside the same resource type, drawable or mipmap included.

The fix is a rename, not a Gradle sync. Change one file’s name so its resource id stops colliding with the other.

Where Does How To Add Image To Android Studio Break Down?

A drawable resource breaks down at the build step far more often than at import, once Gradle sync or AAPT2 fails to turn a placed file into a working resource id.

Format comes before folder, and folder comes before code. Getting the order backwards is where most of the confusion starts.

Vector-or-raster comes first, since it decides which import tool actually applies. The density folder comes second, because nothing can reference the file before it’s sitting in the right place. The code or XML reference comes last, only once the resource id actually exists.

Combine the density scaling ratio with WebP’s average savings and a full five-bucket icon set costs meaningfully less shipped as WebP than as PNG, a gap neither figure states on its own.

That saving costs a touch of decode overhead on first draw. It’s a trade worth taking for a whole icon set, less so for a single one-off graphic you’re only using once.

Once every drawable resource compiles cleanly, the next step is building an APK in Android Studio from that finished resource set.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.