What you describe are three different things:
If you put code in a class that extends BlockBase, then yes, this is a block plugin.
If you add a custom block in the block library, then you store content in the database as block_content.
If you place a block in the block library then you add a block configuration, this is a config entity with the name block.
In a block configuration (3) there can be either a plugin (1) or a block content (2).
You can configure fields in (2), then the storage will be managed by drupal, also for image fields.
If you put form fields in (1) then they are not content, but config. You need submit code to handle this. The result of a file field remains temporary until you decide to save it. And combining config with an uploadable file seems a bit odd, but is possible, see for example the site logo.
Comparing both, I would start with (2) and only use (1) if I need code to make something that (2) does not provide.
Edit: Answer to the comment
If you use (2) you probably should be able to solve most of the tasks you describe in the comment in theming (preprocess + twig).
If not, there may be a solution by using (1) + (2). Put the image in block content (to store it properly in the database), but then use this not as a custom block as in (2), but pull the data in your own plugin. For this put a field in blockForm() to configure the block content id and then use in build() the entity api to load the field data of the configured id.
In fact drupal does the same to get the block content entity into a block, it uses also a plugin for this, but you would make your own.