Direct2D – Drawing rectangeles and circles to large images and saving to disk - image-processing

My task is to draw a lot of simple geometric figures like rectangles and circles to large black-and-white images (about 4000x6000 pixels in size) and save the result to both, bitmap-files and a binary array representing each pixel as 1 if drawn or 0 otherwise. I was using GDI+ (=System.Drawing). Since this, however, took too long, I started having a look at Direct2D. I quickly learned how to draw to a Win32-window and thought I could use this to draw to a bitmap instead.
I learned how to load an image and display it here: https://msdn.microsoft.com/de-de/library/windows/desktop/ee719658(v=vs.85).aspx
But I could not find information on how to create a large ID2D1Bitmap and render to it.
How can I create a render target (must that be a ID2D1HwndRenderTarget?) associated with such a newly created (how?) big bitmap and draw rectangles and circles to it and save it to file, afterwards?
Thank You very much for showing me the right direction,
Jürgen

If I was to do it, I would roll my own code instead of using GDI or DirectX calls. The structure of a binary bitmap is very simple (packed array of bits), and once you have implemented a function to set a single pixel and one to draw a single run (horizontal line segment), drawing rectangles and circles comes easily.
If you don't feel comfortable with bit packing, you can work with a byte array instead (one pixel per byte), and convert the whole image in the end.
Writing the bitmap to a file is also not a big deal once you know about the binary file I/O operations (and you will find many ready-made functions on the Web).
Actually, when you know the specs of the layout of the bitmap file data, you don't need Windows at all.

Related

How to upload multiple images pixel data into one texture in DX12

I have multiple images in forms of pixel arrays. I want to paste them into one big texture and then render the whole texture. For example, I have a car pixel data and a jet pixel data. I want to copy the pixel data of jet at the top of the big texture and copy the pixel data of the car at the bottom of the big texture.
My idea is creating a big buffer and copy these pixel data manually. Manually means calculate the offset of the beginning pixel of each row and copy rows in a loop. Then submit the combined pixel data to GPU. However, I think the method is inefficient as CPU is doing the loop. So I am wonderring is there any other way can improve this. For example, any D3D function already enable me to do the similar thing and effcient. On the other hand, what the most formal/correct way to do such thing?
How have you been uploading your texture data so far? Probably UpdateSubresources from d3dx12.h. Did you try to implement something similar to this function? You can peek in the source - it does roughly the following:
Map intermediate resource (D3D12_HEAP_TYPE_UPLOAD resource created by you),
A sequence of memcpy() to copy pixel data to mapped intermediate resource
Unmap
GPU copy from intermediate to final resource (D3D12_HEAP_TYPE_DEFAULT resource created by you).
You should do something similar and add required offset calculations to step 2, so the subimages are properly laid out. There isn't any more "formal/correct" way to do this, sometimes you have to do some CPU work.

UIBezierPath vs putting png in imageassets

I'm helping create an app that will use images that can be resized (think AutoCAD). Fortunately, I have PaintCode and I have Illustrator so it's very easy for me to convert a svg file into code should I want to.
I converted one image into code and it's around 10,000 lines of code for the image. For speed purposes, is it better to have just a frame with a uiimage inside of it or to use the 10,000 lines of code filled with bezier paths?
I agree with Sami that benchmarking is the best way to answer the question.
In general bitmaps tend to be faster but take more storage space. Vector graphics tend to be smaller, and resolution-independent, but get slower and slower as complexity goes up. (Where bitmap performance is all but independent of image complexity. I say "all but" because some compression formats like JPEG do more work on complex images.)

WebGL - Building objects with block

Im trying to build some text using blocks, which I intend to customize later on. The attached image is a mockup of what i intend to do.
I was thinking of using WebGL, since I want to do it in 3D and I cant do any flash, but Im not sure how to contruct the structure of cubes from the letters. Can anyone give me a suggestion or a technique to map text to a series of points so that seen from far aside they draw that same text?
First, you need a font — a table of shapes for the characters — in a format you can read from your code. Do you already have one? If it's just a few letters, you could manually create polygons for each character.
Then, use a rasterization algorithm to convert the character shape into an array of present-or-absent points/cubes. If you have perfectly flat text, then use a 2D array; if your “customizations” will create depth effects then you will want a 3D array instead (“extruding” the shape by writing it identically into multiple planes of the array).
An alternative to the previous two steps, which is appropriate if your text does not vary at runtime, is to first create an image with your desired text on it, then use the pixels of the image as the abovementioned 2D array. In the browser, you can do this by using the 2D Canvas feature to draw an image onto a canvas and then reading the pixels out from it.
Then to produce a 3D shape from this voxel array, construct a polygon face for every place in the array where a “present” point meets an “absent” point. If you do this based on pairs of neighbors, you get a chunky pixel look (like Minecraft). If you want smooth slopes (like your example image), then you need a more complex technique; the traditional way to produce a smooth surface is marching cubes (but just doing marching cubes will round off all your corners).

How can I render a square bitmap to an arbitrary four-sided polygon using GDI?

I need to paint a square image, mapped or transformed to an unknown-at-compile-time four-sided polygon. How can I do this?
Longer explanation
The specific problem is rendering a map tile with a non-rectangular map projection. Suppose I have the following tile:
and I know the four corner points need to be here:
Given that, I would like to get the following output:
The square tile may be:
Rotated; and/or
Be narrower at one end than at the other.
I think the second item means this requires a non-affine transformation.
Random extra notes
Four-sided? It is plausible that to be completely correct, the tile should be
mapped to a polygon with more than four points, but for our purposes
and at the scale it is drawn, a square -> other four-cornered-polygon
transformation should be enough.
Why preferably GDI only? All rendering so far is done using GDI, and I want to keep the code (a) fast and (b) requiring as few extra
libraries as possible. I am aware of some support for
transformations in GDI and have been experimenting with them
today, but even after experimenting with them I'm not sure if they're
flexible enough for this purpose. If they are, I haven't managed to
figure it out, and so I'd really appreciate some sample code.
GDI+ is also ok since we use it elsewhere, but I know it can be slow, and speed is
important here.
One other alternative is anything Delphi- /
C++Builder-specific; this program is written mostly in C++ using
the VCL, and the graphics in question are currently painted to a
TCanvas with a mix of TCanvas methods and raw WinAPI/GDI calls.
Overlaying images: One final caveat is that one colour in the tile may be for color-key
transparency: that is, all the white (say) squares in the above tile
should be transparent when drawn over whatever is underneath.
Currently, tiles are drawn to square or axis-aligned rectangular
targets using TransparentBlt.
I'm sorry for all the extra caveats that make this question more complicated
than 'what algorithm should I use?' But I will happily accept answers with
only algorithmic information too.
You might also want to have a look at Graphics32.
The screen shot bewlow shows how the transfrom demo in GR32 looks like
Take a look at 3D Lab Vector graphics. (Specially "Football field" in the demo).
Another cool resource is AggPas with full source included (download)
AggPas is Open Source and free of charge 2D vector graphics library. It is an Object Pascal native port of the Anti-Grain Geometry library - AGG, originally written by Maxim Shemanarev in C++. AggPas doesn't depend on any graphic API or technology. Basically, you can think of AggPas as of a rendering engine that produces pixel images in memory from some vectorial data.
Here is how the perspective demo looks like:
After transformation:
The general technique is described in George Wolberg's "Digital Image Warping". It looks like this abstract contains the relevant math, as does this paper. You need to create a perspective matrix that maps from one quad to another. The above links show how to create the matrix. Once you have the matrix, you can scan your output buffer, perform the transformation (or possibly the inverse - depending on which they give you), and that will give you points in the original image that you can copy from.
It might be easier to use OpenGL to draw a textured quad between the 4 points, but that doesn't use GDI like you wanted.

Understanding just what is an image

I suppose the simplest understanding of what a (bitmap) image is would be an array of pixels. After that, it gets pretty technical.
I've been trying to understand the sort of information that an image may provide and have come across a large collection of technical terms like "mipmap", "pitch", "stride", "linear", "depth", as well as other format-specific things.
These seem to pop up across a lot of different formats so it'd probably be useful to understand what purpose they serve in an image. Looking at the DDS, BMP, PNG, TGA, JPG documentations has only made it clear that an image is pretty confusing.
Though searching around for some hours, there wasn't any nice tutorial-like break-down of just what an image is and all of the different properties.
The eventual goal would be to take proprietary image formats and convert them to more common formats like DDS or BMP. Or to make up some image format.
Any good readings?
Even your simplified explanation of an image doesn't encompass all the possibilities. For example an image can be divided by planes, where the red pixel values are all together followed by the green pixel values, followed by the blue pixel values. Such layouts are uncommon but still possible.
Assuming a simple layout of pixels you must still determine the pixel format. You might have a paletted image where some number of bits (1, 4, or 8) will be an index into a palette or color table which will define the RGB color of the pixel along with the transparency of the pixel (one index will typically be reserved as a transparent pixel). Otherwise the pixel will be 3 or 4 bytes depending on whether a transparency or alpha value is included. The order of the values (R,G,B) or (B,G,R) will depend on the format - Windows bitmaps are B,G,R while everything else will most likely be R,G,B.
The stride is the number of bytes between rows of the image. Windows bitmaps for example will take the width of the image times the number of bytes per pixel and round it up to the next multiple of 4 bytes.
I've never heard of DDA, and BMP is only common in the Windows world (and there's a lot more computing in the non-windows world than you might think). Rather than worry about all of the technical details of this, why not just use an existing toolkit such as image magick, which can already batch convert from dozens of formats to your one common format?
Unless you're doing specialized work, where you would need something fancy like hdr (which most image formats don't even support -- so most of your sources would not have it in the first place), you're probably best off picking something standard like PNG or JPG. They both have plusses and minuses. You might want to support both of those depending on the image.

Resources