diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp
index eb8cb178d1b844fff57892c7312ed71d325900cc..466559df8e5fb4d7c1d9e8342e4083e1f0596695 100644
--- a/include/vkcv/BufferManager.hpp
+++ b/include/vkcv/BufferManager.hpp
@@ -22,6 +22,7 @@ namespace vkcv
 	class BufferManager
 	{
 		friend class Core;
+		friend class ImageManager;
 	private:
 		
 		struct Buffer
diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp
index 3c211402ffdc00a3cf7ee10ef7d0e557589af121..a7de56cf527e177a7ba29a406d4f9dbea22eed12 100644
--- a/include/vkcv/Image.hpp
+++ b/include/vkcv/Image.hpp
@@ -4,16 +4,18 @@
  * @file vkcv/Buffer.hpp
  * @brief class for image handles
  */
-#include "ImageManager.hpp"
+#include "vulkan/vulkan.hpp"
 
 namespace vkcv {
+	class ImageManager;
 	class Image {
 	public:
 		static Image create(ImageManager* manager, uint32_t width, uint32_t height);
-		void switchImageLayout(vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
+		void switchImageLayout(vk::ImageLayout newLayout); 
 	private:
 		ImageManager* const m_manager;
 		const uint64_t m_handle_id;
+		vk::ImageLayout m_layout;
 
 		Image(ImageManager* manager, uint64_t id);
 	};
diff --git a/include/vkcv/ImageManager.hpp b/include/vkcv/ImageManager.hpp
index b4fe888e3007d4263030ae0c344bc878e0651c9f..faf974b7272e96feb74960ecc1b7b8fa119bc706 100644
--- a/include/vkcv/ImageManager.hpp
+++ b/include/vkcv/ImageManager.hpp
@@ -9,7 +9,8 @@
 
 namespace vkcv {
 	class Core;
-	class ImageManager 
+	class BufferManager;
+	class ImageManager
 	{
 		friend class Core;
 	private:
@@ -17,11 +18,13 @@ namespace vkcv {
 		{
 			vk::Image m_handle;
 			vk::DeviceMemory m_memory;
-			void* m_mapped = nullptr;
-			bool m_mappable;
 		};
 		Core* m_core;
+		vk::Buffer m_stagingBuffer;
+		vk::DeviceMemory m_stagingMemory;
+
 		std::vector<Image> m_images;
+		void init(BufferManager* bufferManager);
 		ImageManager() noexcept;
 	public:
 		~ImageManager() noexcept;
@@ -30,9 +33,9 @@ namespace vkcv {
 
 		ImageManager& operator=(ImageManager&& other) = delete;
 		ImageManager& operator=(const ImageManager& other) = delete;
-
-		void copyBufferToImage(vk::Buffer buffer, vk::Image image, uint32_t width, uint32_t height);
+		
 		void switchImageLayout(uint64_t id, vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
+		void fillImage(uint64_t id, void* data, size_t size);
 
 		uint64_t createImage(uint32_t width, uint32_t height);
 
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 4fc53eb90fd1e0121170e3f3849e3ba42b4a9b05..66156843b8ed3861f9eefe3524c59b0dadf6d366 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -10,6 +10,7 @@
 #include "PassManager.hpp"
 #include "PipelineManager.hpp"
 #include "vkcv/BufferManager.hpp"
+#include "vkcv/ImageManager.hpp"
 #include "Surface.hpp"
 #include "ImageLayoutTransitions.hpp"
 #include "Framebuffer.hpp"
@@ -100,6 +101,7 @@ namespace vkcv
     	m_BufferManager->m_core = this;
     	m_BufferManager->init();
 		m_ImageManager->m_core = this;
+		m_ImageManager->init(m_BufferManager.get());
 	}
 
 	Core::~Core() noexcept {
diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp
index 887bf3b29adcd1d7e9490ab2820545b28691d3a6..cd41c0e2a87ba5949050c50ddb8b094fc1634f3f 100644
--- a/src/vkcv/Image.cpp
+++ b/src/vkcv/Image.cpp
@@ -4,6 +4,7 @@
  * @brief class for image handles
  */
 #include "vkcv/Image.hpp"
+#include "vkcv/ImageManager.hpp"
 
 namespace vkcv{
 	Image Image::create(ImageManager* manager, uint32_t width, uint32_t height)
@@ -11,13 +12,15 @@ namespace vkcv{
 		return Image(manager, manager->createImage(width, height));
 	}
 
-	void Image::switchImageLayout(vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout)
+	void Image::switchImageLayout(vk::ImageLayout newLayout)
 	{
-		m_manager->switchImageLayout(m_handle_id, oldLayout, newLayout);
+		m_manager->switchImageLayout(m_handle_id, m_layout, newLayout);
+		m_layout = newLayout;
 	}
 	Image::Image(ImageManager* manager, uint64_t id) :
 		m_manager(manager),
-		m_handle_id(id)
+		m_handle_id(id),
+		m_layout(vk::ImageLayout::eUndefined)
 	{
 	}
 
diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp
index 46d703b453823c898639ab927c0f0929bbc7a937..38e0b554f2ec8d4b19c94d0b5898b6649749f721 100644
--- a/src/vkcv/ImageManager.cpp
+++ b/src/vkcv/ImageManager.cpp
@@ -34,6 +34,15 @@ namespace vkcv {
 		return -1;
 	}
 	
+	void ImageManager::init(BufferManager* bufferManager)
+	{
+		if (!m_core) {
+			return;
+		}
+		uint64_t stagingID = bufferManager->createBuffer(BufferType::STAGING, 1024 * 1024, BufferMemoryType::HOST_VISIBLE);
+		m_stagingBuffer = bufferManager->m_buffers[stagingID].m_handle;
+	}
+
 	ImageManager::ImageManager() noexcept :
 		m_core(nullptr), m_images()
 	{
@@ -45,25 +54,7 @@ namespace vkcv {
 		}
 	}
 
-	void ImageManager::copyBufferToImage(vk::Buffer buffer, vk::Image image, uint32_t width, uint32_t height)
-	{
-		vk::BufferImageCopy copyRegion(0,width,height); // possibly add offset etc
-
-		SubmitInfo submitInfo;
-		submitInfo.queueType = QueueType::Transfer; //not sure
-		m_core->submitCommands(
-			submitInfo,
-			[buffer, image,copyRegion](const vk::CommandBuffer& commandBuffer) {
-				commandBuffer.copyBufferToImage(
-					buffer,
-					image,vk::ImageLayout::eTransferDstOptimal,
-					copyRegion
-				);
-			},
-			[]() {}
-			);
-
-	}
+	
 
 
 	uint64_t ImageManager::createImage(uint32_t width, uint32_t height)
@@ -95,7 +86,6 @@ namespace vkcv {
 		const vk::PhysicalDevice& physicalDevice = m_core->getContext().getPhysicalDevice();
 
 		vk::MemoryPropertyFlags memoryTypeFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent;
-		bool mappable = false;
 
 		const uint32_t memoryTypeIndex = searchImageMemoryType(
 			physicalDevice.getMemoryProperties(),
@@ -107,7 +97,7 @@ namespace vkcv {
 		device.bindImageMemory(image, memory, 0);
 
 		const uint64_t id = m_images.size();
-		m_images.push_back({ image, memory, nullptr, mappable });
+		m_images.push_back({ image, memory});
 		return id;
 	}
 
@@ -154,10 +144,114 @@ namespace vkcv {
 					imageMemoryBarrier
 				);
 			},
-			[]() {}
+			nullptr
 		);
 	}
 
+	struct ImageStagingStepInfo {
+		void* data;
+		size_t size;
+		uint32_t width;
+		uint32_t height;
+		size_t offset;
+
+		vk::Image image;
+		vk::Buffer stagingBuffer;
+		vk::DeviceMemory stagingMemory;
+
+		size_t stagingLimit;
+		size_t stagingPosition;
+	};
+
+	void copyStagingToImage(Core* core, ImageStagingStepInfo info)
+	{
+		/*
+		* Alte implementation
+		vk::BufferImageCopy copyRegion(0, width, height);
+
+		SubmitInfo submitInfo;
+		submitInfo.queueType = QueueType::Transfer; //not sure
+		core->submitCommands(
+			submitInfo,
+			[buffer, image, copyRegion](const vk::CommandBuffer& commandBuffer) {
+				commandBuffer.copyBufferToImage(
+					buffer,
+					image, vk::ImageLayout::eTransferDstOptimal,
+					copyRegion
+				);
+			},
+			[]() {}
+			);
+		*/
+
+		const size_t remaining = info.size - info.stagingPosition;
+		const size_t mapped_size = std::min(remaining, info.stagingLimit);
+
+		const vk::Device& device = core->getContext().getDevice();
+
+		void* mapped = device.mapMemory(info.stagingMemory, 0, mapped_size);
+		memcpy(mapped, reinterpret_cast<char*>(info.data) + info.stagingPosition, mapped_size);
+		device.unmapMemory(info.stagingMemory);
+
+		SubmitInfo submitInfo;
+		submitInfo.queueType = QueueType::Transfer;
+
+		core->submitCommands(
+			submitInfo,
+			[&info, &mapped_size](const vk::CommandBuffer& commandBuffer) {
+				/*
+				const vk::BufferImageCopy region(
+					info.offset, //bufferOffset
+					info.size, //bufferRowlength
+					0, //bufferImageHeight
+					vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor,0,0,1),//soubresource layer
+					vk::Offset2D(info.offset,0), //imageoffset
+					vk::Extent3D(info.width,info.height,1) //extend3d
+				);
+				
+				commandBuffer.copyBufferToImage(
+					info.stagingBuffer,
+					info.image,
+					vk::ImageLayout::eTransferDstOptimal,
+					region);
+				*/
+			},
+			[&core, &info, &mapped_size, &remaining]() {
+				if (mapped_size < remaining) {
+					info.stagingPosition += mapped_size;
+
+					copyStagingToImage(
+						core,
+						info
+					);
+				}
+			}
+			);
+	}
+	void ImageManager::fillImage(uint64_t id, void* data, size_t size)
+	{
+		uint64_t width =0, height = 0; // TODO
+		//Image wird geladen	
+		size_t sizeImage = width * height * 3; //TODO
+		switchImageLayout(id, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal);
+		//const size_t max_size = std::min(size, image.m_size - offset);
+		ImageStagingStepInfo info;
+		info.data = data;
+		info.size = size;//TODO
+		info.offset = 0;
+
+		info.image = m_images[id].m_handle;
+		info.stagingBuffer = m_stagingBuffer;
+		info.stagingMemory = m_stagingMemory;
+
+		const vk::MemoryRequirements stagingRequirements = m_core->getContext().getDevice().getBufferMemoryRequirements(m_stagingBuffer);
+		info.stagingLimit = stagingRequirements.size;
+		info.stagingPosition = 0;
+
+		copyStagingToImage(m_core, info);
+		switchImageLayout(id, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal);
+	}
+
 	void ImageManager::destroyImage(uint64_t id)
 	{
 		if (id >= m_images.size()) {