bool ResourceManager::AddImage(const boost::filesystem::path& path, const std::string& imgname, const float width, const float height, const std::string& key) { if(!boost::filesystem::is_regular_file(path/imgname)) { Logger::Critical(LogOrigin::RESOURCEMANAGER, "Tried loading image path'"+(path/imgname).string()+"' but this image path doesn't exist!"); exit(1); } // create Original file path std::string originalFile = (path / imgname).string(); // if the optional param key is not given, use the basename as key std::string image_key = ""; if(key == "") { image_key = boost::filesystem::basename(originalFile); } else { image_key = key; } // Create Cache Paths boost::filesystem::path cacheDir = (path / "cached").string(); std::string cacheFile = (cacheDir / image_key ).string()+".png"; // if an image with that key already exists in the dictionary, return if(mImages.count(image_key) != 0) { return true; } // Log output Logger::Debug(LogOrigin::RESOURCEMANAGER, "Caching image " + originalFile); // Create cache directory boost::filesystem::create_directory(cacheDir.string()); // Load, convert and save image (originalFile > cacheFile) Magick::Image mimage; mimage.backgroundColor(Magick::Color(0, 0, 0, 65535)); mimage.density(Magick::Geometry(144, 144)); mimage.read(originalFile); // Conver floats to view pixels so that images will always be at the same scale const Vector2D vec(Coordinates::WorldFloatToWorldPixel(Vector2D(width, height))); mimage.zoom(Magick::Geometry(vec.x, vec.y)); mimage.depth(8); mimage.write(cacheFile); // Load cached file sf::Image sfimage; sfimage.LoadFromFile(cacheFile); sfimage.SetSmooth(true); // Save loaded Image in Dictionary // mImages.insert(new std::pair<std::string, sf::Image>(image_key, sfimage)); mImages[image_key] = sfimage; return true; }
/** layerToImage * * Converts a layer into an ImageMagick Image */ int HandlerUtils::LayerToImage(const Map& map, const Layer& layer, Magick::Image& image) { std::vector<Magick::Image> tiles; if (HandlerUtils::GetTiles(map, tiles)) return -1; Magick::Color color = Magick::ColorRGB(0, 0, 0); color.alpha(0); int width = map.GetWidth() * map.GetTileWidth(); int height = map.GetHeight() * map.GetTileHeight(); image.matte(true); image.resize(Magick::Geometry(width, height)); image.backgroundColor(color); image.erase(); return HandlerUtils::LayerToImage(map, layer, tiles, image); }
/** MapToImage * * Converts a map into an ImageMagick Image */ int HandlerUtils::MapToImage(const Map& map, Magick::Image& image) { std::vector<Magick::Image> tiles; if (HandlerUtils::GetTiles(map, tiles)) return -1; Magick::Color color = Magick::ColorRGB(0, 0, 0); color.alpha(0); const Tileset& tileset = map.GetTileset(); uint32_t tile_width, tile_height; tileset.GetTileDimensions(tile_width, tile_height); int width = map.GetWidth() * tile_width; int height = map.GetHeight() * tile_height; image.matte(true); image.resize(Magick::Geometry(width, height)); image.backgroundColor(color); image.erase(); try { for (const auto& layer : map.GetLayers()) { if (HandlerUtils::LayerToImage(map, layer, tiles, image)) return -1; } } catch (Magick::Exception& error_) { return -1; } return 0; }
bool ResourceManager::AddTexture(const boost::filesystem::path& path, const std::string& imgname, const float width, const float height) { if(!boost::filesystem::is_regular_file(path/imgname)) { std::cerr << "Tried loading image path '" << (path/imgname).string() << "' but this image path doesn't exist!" << std::endl; exit(1); } // convert coords const Vector2D size(Coordinates::WorldFloatToWorldPixel(Vector2D(width, height))); // create Original file path std::string originalFile = (path / imgname).string(); // if the optional param key is not given, use the basename as key std::string image_key = boost::filesystem::basename(originalFile); // Create Cache Paths boost::filesystem::path cacheDir = (path / "cached").string(); std::string cacheFile = (cacheDir / image_key ).string()+".png"; // if an image with that key already exists in the dictionary, return if(mTextures.count(image_key) != 0) { return true; } sf::Texture sftexture; bool cache = true; if(boost::filesystem::is_regular_file(cacheFile)) { // Load cached file bool success = sftexture.LoadFromFile(cacheFile); if (success && (int)sftexture.GetHeight() == (int)size.x && (int)sftexture.GetWidth() == (int)size.y) { cache = false; std::cout << "Texture " << originalFile << " already exists. Not caching. "<< std::endl; } else if (success) { std::cout << "Texture " << originalFile << " does not exist in the resolution " << size.x << "x" << size.y << " but in " << sftexture.GetHeight() << "x" << sftexture.GetWidth() << "." << std::endl; } } if(cache){ std::cout << ":: Caching image " << originalFile << std::endl; // Create cache directory boost::filesystem::create_directory(cacheDir.string()); // Load, convert and save image (originalFile > cacheFile) Magick::Image mimage; mimage.backgroundColor(Magick::Color(0, 0, 0, 65535)); mimage.density(Magick::Geometry(144, 144)); mimage.read(originalFile); mimage.zoom(Magick::Geometry(std::max(size.x,size.y), std::max(size.x,size.y))); mimage.depth(8); mimage.write(cacheFile); // Load cached file sftexture.LoadFromFile(cacheFile); } sftexture.SetSmooth(true); //std::cout << " Added image: "<<image_key << std::endl; // Save loaded Texture in Dictionary mTextures[image_key] = sftexture; return true; }
/******************************************************************************* * Operations. ******************************************************************************/ ColorLevels::Statistics ColorLevels::getColorLevels( ColorLevels::Options options, std::string imagePath, Magick::Blob* blob) { Magick::Image image; try { image.read(imagePath); } catch (Magick::Exception &e) { throw std::runtime_error(e.what()); } /* For simplicity, only support sRGB */ if (image.colorSpace() != Magick::sRGBColorspace) throw std::logic_error("Unsupported colorspace"); /* Convert sRGB to Lab colorspace */ image.colorSpace(Magick::ColorspaceType::LabColorspace); ColorLevels::Statistics imageStats; imageStats.width = image.size().width(); imageStats.height = image.size().height(); imageStats.redPixels = 0; imageStats.purplePixels = 0; imageStats.backgroundPixels = 0; const Magick::PixelPacket *pixels = image.getConstPixels( 0, 0, imageStats.width, imageStats.height); /* Setup image masks */ Magick::Image maskTransparentImage, maskOriginalImage; Magick::PixelPacket *maskTransparentPixels, *maskOriginalPixels; if (options.drawMaskOverTransparent) { maskTransparentImage = Magick::Image(Magick::Geometry( imageStats.width, imageStats.height), Magick::Color("rgba(0,0,0,0)")); maskTransparentPixels = maskTransparentImage.getPixels(0, 0, imageStats.width, imageStats.height); } if (options.drawMaskOverOriginalImage) { maskOriginalImage = Magick::Image(imagePath); maskOriginalPixels = maskOriginalImage.getPixels(0, 0, imageStats.width, imageStats.height); } /* Sanity check color coordinates */ if (options.redCoordinateSet) { if (options.redCoordinate.x >= imageStats.width) throw std::runtime_error("Invalid red X value."); if (options.redCoordinate.y >= imageStats.height) throw std::runtime_error("Invalid red Y value."); } if (options.purpleCoordinateSet) { if (options.purpleCoordinate.x >= imageStats.width) throw std::runtime_error("Invalid purple X value."); if (options.purpleCoordinate.y >= imageStats.height) throw std::runtime_error("Invalid purple Y value."); } if (options.backgroundCoordinateSet) { if (options.backgroundCoordinate.x >= imageStats.width) throw std::runtime_error("Invalid background X value."); if (options.backgroundCoordinate.y >= imageStats.height) throw std::runtime_error("Invalid background Y value."); } /* Setup colors */ const ColorLevels::LAB red = options.redCoordinateSet ? ColorLevels::LABColorToLAB(static_cast<Magick::ColorRGB>( pixels[(imageStats.width * options.redCoordinate.x) + options.redCoordinate.y])) : ColorLevels::getLABValueOfRGBColor( Magick::ColorRGB(options.redColor)); if (options.redCoordinateSet && options.verbose) std::cout << "Red color: " << red << std::endl; const ColorLevels::LAB purple = options.purpleCoordinateSet ? ColorLevels::LABColorToLAB(static_cast<Magick::ColorRGB>( pixels[(imageStats.width * options.purpleCoordinate.x) + options.purpleCoordinate.y])) : ColorLevels::getLABValueOfRGBColor( Magick::ColorRGB(options.purpleColor)); if (options.purpleCoordinateSet && options.verbose) std::cout << "Purple color: " << purple << std::endl; const Magick::ColorRGB redMaskColor("#00FF00"); const Magick::ColorRGB purpleMaskColor("#0000FF"); const Magick::ColorRGB backgroundMaskColor("#000000"); /* backgroundColor() returns an sRGB value, even in LAB colorspace */ const ColorLevels::LAB backgroundColor = options.backgroundCoordinateSet ? ColorLevels::LABColorToLAB(static_cast<Magick::ColorRGB>( pixels[(imageStats.width * options.backgroundCoordinate.x) + options.backgroundCoordinate.y])) : ColorLevels::getLABValueOfRGBColor( options.backgroundColor == "" ? image.backgroundColor() : Magick::ColorRGB(options.backgroundColor)); if ((options.backgroundCoordinateSet || options.backgroundColor == "") && options.verbose) std::cout << "Background color: " << backgroundColor << std::endl; for (size_t row = 0; row < imageStats.height; row++) { for (size_t col = 0; col < imageStats.width; col++) { /* Get color of current pixel */ size_t offset = (imageStats.width * row) + col; ColorLevels::LAB currentPixelLAB = ColorLevels::LABColorToLAB( static_cast<Magick::ColorRGB>(pixels[offset])); /* Check pixel for background */ if (ColorLevels::CIEDE2000(backgroundColor, currentPixelLAB) < options.backgroundThreshold) { imageStats.backgroundPixels++; if (options.drawMaskOverTransparent) maskTransparentPixels[offset] = backgroundMaskColor; if (options.drawMaskOverOriginalImage) maskOriginalPixels[offset] = backgroundMaskColor; /* Check pixel for red */ } else if (ColorLevels::CIEDE2000(red, currentPixelLAB) < options.redThreshold) { imageStats.redPixels++; if (options.drawMaskOverTransparent) maskTransparentPixels[offset] = redMaskColor; if (options.drawMaskOverOriginalImage) maskOriginalPixels[offset] = redMaskColor; /* Check pixel for purple */ } else if (ColorLevels::CIEDE2000(purple, currentPixelLAB) < options.purpleThreshold) { imageStats.purplePixels++; if (options.drawMaskOverTransparent) maskTransparentPixels[offset] = purpleMaskColor; if (options.drawMaskOverOriginalImage) maskOriginalPixels[offset] = purpleMaskColor; } } } /* Save masks */ if (options.drawMaskOverTransparent) { maskTransparentImage.syncPixels(); maskOriginalImage.write(blob); // maskTransparentImage.write( // ColorLevels::basenameWithoutExtension(imagePath) + // "_mask_transparent.png"); } if (options.drawMaskOverOriginalImage) { maskOriginalImage.syncPixels(); maskOriginalImage.write(blob); // maskOriginalImage.write( // ColorLevels::basenameWithoutExtension(imagePath) + // "_mask_original.png"); } std::cout << "ok?" << blob->length() << "\n"; return (imageStats); }
void Magick::backgroundColorImage::operator()( Magick::Image &image_ ) const { image_.backgroundColor( _color ); }