<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bilder verkleinern]]></title><description><![CDATA[<p>Hi,<br />
ich brauchte eine Routine zum skalieren von Grafiken für mein Programm, und das ganze sollte natürlich schnell sein. Deswegen dachte ich: Du hörst immer: Divisionen und Fließkommarechnung ist langsam, also verzichtest du sogut wie möglich darauf.</p>
<p>Also hab ich mir ein bisschen Gedanken gemacht und dann hab ich auch ein bisschen programmiert. Meine Funktion kann nun Grafiken verkleinern (das reicht momentan erstmal) und benötigt dafür nur zwei Divisionen, diverse Bitverschiebungen und keine Fließkommazahlen.</p>
<p>Einziges Problem: Das ganze bringt es auf nicht mehr als etwa 15-20 Bilder, die von 640x480 auf 480x360 runterskaliert werden. Da ich das jedoch im Zusammenhang mit Video benutzen möchte, wären 30 Bilder pro Sekunde schon angebracht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /></p>
<p>Deswegen meine Frage: wie kann ich die Funktion beschleunigen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /><br />
Gruß, Olli</p>
<p>Meine Funktion:<br />
die verwendeten eigenen Funktionen (image_create, image_get_row, etc) sollten selbsterklärend sein <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /></p>
<pre><code class="language-cpp">li_image *image_get_scaled( li_image *source, int width, int height ) {
	if( source-&gt;width == width &amp;&amp; source-&gt;height == height )
		return image_create_copy( source );

	FV_StartTimer( 0 );

	li_image *scaled_x = NULL, *scaled_y = NULL;

	if( source-&gt;width != width ) {
		scaled_x = image_create( width, source-&gt;height );

		if( width &lt; source-&gt;width ) {
			int x, y, i;
			int *lookup_x = malloc( sizeof( int ) * source-&gt;width * 3 );
			int *row_output = malloc( sizeof( int ) * width * 4 );

			int factor = (width &lt;&lt; 8) / source-&gt;width;
			for( x = 0; x &lt; source-&gt;width; x++ ) {
				int dx = factor * x;
				int dxr = dx &amp; 0xff;

				int weight_1 = li_min( 255 - dxr, factor );
				int weight_2 = factor - weight_1;

				lookup_x[ 3 * x ] = dx &gt;&gt; 8;
				lookup_x[ 3 * x + 1 ] = weight_1;
				lookup_x[ 3 * x + 2 ] = weight_2;
			}

			for( y = 0; y &lt; source-&gt;height; y++ ) {
				li_color *row_source = image_get_row( source, y );
				li_color *row_scaled = image_get_row( scaled_x, y );
				memset( row_output, 0, sizeof( int ) * width * 4 );

				for( x = 0; x &lt; source-&gt;width; x++ ) {
					for( i = 0; i &lt; 4; i++ ) {
						int dx = lookup_x[ 3 * x ];
						row_output[ 4 * dx + i ] +=	(row_source[x].v[i] * lookup_x[ 3 * x + 1 ]);

						if( lookup_x[ 3 * x + 2 ] &amp;&amp; dx + 1 &lt; width )
							row_output[ 4 * (dx + 1) + i ] += (row_source[x].v[i] * lookup_x[ 3 * x + 2 ] );
					}
				}

				for( x = 0; x &lt; width; x++ ) {
					for( i = 0; i &lt; 4; i++ )
						(row_scaled + x)-&gt;v[i] = (row_output[ 4 * x + i ] &gt;&gt; 8) &amp; 0xff;
				}

			}

			free( row_output );
			free( lookup_x );
		}
	}

	if( source-&gt;height != height ) {
		if( scaled_x ) source = scaled_x;

		scaled_y = image_create( source-&gt;width, height );

		if( height &lt; source-&gt;height ) {
			int x, y, i;
			int *lookup_y = malloc( sizeof( int ) * source-&gt;height * 3 );
			int *col_output = malloc( sizeof( int ) * height * 4 );

			int factor = (height &lt;&lt; 8) / source-&gt;height;
			for( y = 0; y &lt; source-&gt;height; y++ ) {
				int dy = factor * y;
				int dyr = dy &amp; 0xff;

				int weight_1 = li_min( 256 - dyr, 192 );
				int weight_2 = 192 - weight_1;

				lookup_y[ 3 * y ] = dy &gt;&gt; 8;
				lookup_y[ 3 * y + 1 ] = weight_1;
				lookup_y[ 3 * y + 2 ] = weight_2;
			}

			for( x = 0; x &lt; source-&gt;width; x++ ) {
				memset( col_output, 0, sizeof( int ) * height * 4 );
				li_color *col_source = source-&gt;data + x;

				for( y = 0; y &lt; source-&gt;height; y++ ) {
					for( i = 0; i &lt; 4; i++ ) {
						int dy = lookup_y[ 3 * y];
						col_output[ 4 * dy + i ] +=
								col_source[ y * source-&gt;width ].v[i] * lookup_y[ 3 * y + 1 ];

						if( lookup_y[ 3 * y + 2 ] &amp;&amp; dy + 1 &lt; height ) {
							col_output[ 4 * (dy + 1) + i ] +=
									col_source[ y * source-&gt;width ].v[i] * lookup_y[ 3 * y + 2 ];
						}
					}
				}

				for( y = 0; y &lt; height; y++ ) {
					for( i = 0; i &lt; 4; i++ )
						(scaled_y-&gt;data + y * width + x)-&gt;v[i] =
							(unsigned char)(col_output[ 4 * y + i ] &gt;&gt; 8);
				}

			}

			free( col_output );
			free( lookup_y );
		}
	}

	if( scaled_y ) {
		if( scaled_x )
			image_destroy( scaled_x );

		FV_StopTimer( 0 );
		return scaled_y;
	}

	if( scaled_x &amp;&amp; !scaled_y ) {
		FV_StopTimer( 0 );
		return scaled_x;
	}

	return NULL;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/194577/bilder-verkleinern</link><generator>RSS for Node</generator><lastBuildDate>Tue, 30 Jun 2026 07:01:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/194577.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 Oct 2007 16:19:02 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Bilder verkleinern on Mon, 08 Oct 2007 16:28:47 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich brauchte eine Routine zum skalieren von Grafiken für mein Programm, und das ganze sollte natürlich schnell sein. Deswegen dachte ich: Du hörst immer: Divisionen und Fließkommarechnung ist langsam, also verzichtest du sogut wie möglich darauf.</p>
<p>Also hab ich mir ein bisschen Gedanken gemacht und dann hab ich auch ein bisschen programmiert. Meine Funktion kann nun Grafiken verkleinern (das reicht momentan erstmal) und benötigt dafür nur zwei Divisionen, diverse Bitverschiebungen und keine Fließkommazahlen.</p>
<p>Einziges Problem: Das ganze bringt es auf nicht mehr als etwa 15-20 Bilder, die von 640x480 auf 480x360 runterskaliert werden. Da ich das jedoch im Zusammenhang mit Video benutzen möchte, wären 30 Bilder pro Sekunde schon angebracht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /></p>
<p>Deswegen meine Frage: wie kann ich die Funktion beschleunigen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /><br />
Gruß, Olli</p>
<p>Meine Funktion:<br />
die verwendeten eigenen Funktionen (image_create, image_get_row, etc) sollten selbsterklärend sein <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title="=)"
      alt="🙂"
    /></p>
<pre><code class="language-cpp">li_image *image_get_scaled( li_image *source, int width, int height ) {
	if( source-&gt;width == width &amp;&amp; source-&gt;height == height )
		return image_create_copy( source );

	FV_StartTimer( 0 );

	li_image *scaled_x = NULL, *scaled_y = NULL;

	if( source-&gt;width != width ) {
		scaled_x = image_create( width, source-&gt;height );

		if( width &lt; source-&gt;width ) {
			int x, y, i;
			int *lookup_x = malloc( sizeof( int ) * source-&gt;width * 3 );
			int *row_output = malloc( sizeof( int ) * width * 4 );

			int factor = (width &lt;&lt; 8) / source-&gt;width;
			for( x = 0; x &lt; source-&gt;width; x++ ) {
				int dx = factor * x;
				int dxr = dx &amp; 0xff;

				int weight_1 = li_min( 255 - dxr, factor );
				int weight_2 = factor - weight_1;

				lookup_x[ 3 * x ] = dx &gt;&gt; 8;
				lookup_x[ 3 * x + 1 ] = weight_1;
				lookup_x[ 3 * x + 2 ] = weight_2;
			}

			for( y = 0; y &lt; source-&gt;height; y++ ) {
				li_color *row_source = image_get_row( source, y );
				li_color *row_scaled = image_get_row( scaled_x, y );
				memset( row_output, 0, sizeof( int ) * width * 4 );

				for( x = 0; x &lt; source-&gt;width; x++ ) {
					for( i = 0; i &lt; 4; i++ ) {
						int dx = lookup_x[ 3 * x ];
						row_output[ 4 * dx + i ] +=	(row_source[x].v[i] * lookup_x[ 3 * x + 1 ]);

						if( lookup_x[ 3 * x + 2 ] &amp;&amp; dx + 1 &lt; width )
							row_output[ 4 * (dx + 1) + i ] += (row_source[x].v[i] * lookup_x[ 3 * x + 2 ] );
					}
				}

				for( x = 0; x &lt; width; x++ ) {
					for( i = 0; i &lt; 4; i++ )
						(row_scaled + x)-&gt;v[i] = (row_output[ 4 * x + i ] &gt;&gt; 8) &amp; 0xff;
				}

			}

			free( row_output );
			free( lookup_x );
		}
	}

	if( source-&gt;height != height ) {
		if( scaled_x ) source = scaled_x;

		scaled_y = image_create( source-&gt;width, height );

		if( height &lt; source-&gt;height ) {
			int x, y, i;
			int *lookup_y = malloc( sizeof( int ) * source-&gt;height * 3 );
			int *col_output = malloc( sizeof( int ) * height * 4 );

			int factor = (height &lt;&lt; 8) / source-&gt;height;
			for( y = 0; y &lt; source-&gt;height; y++ ) {
				int dy = factor * y;
				int dyr = dy &amp; 0xff;

				int weight_1 = li_min( 256 - dyr, 192 );
				int weight_2 = 192 - weight_1;

				lookup_y[ 3 * y ] = dy &gt;&gt; 8;
				lookup_y[ 3 * y + 1 ] = weight_1;
				lookup_y[ 3 * y + 2 ] = weight_2;
			}

			for( x = 0; x &lt; source-&gt;width; x++ ) {
				memset( col_output, 0, sizeof( int ) * height * 4 );
				li_color *col_source = source-&gt;data + x;

				for( y = 0; y &lt; source-&gt;height; y++ ) {
					for( i = 0; i &lt; 4; i++ ) {
						int dy = lookup_y[ 3 * y];
						col_output[ 4 * dy + i ] +=
								col_source[ y * source-&gt;width ].v[i] * lookup_y[ 3 * y + 1 ];

						if( lookup_y[ 3 * y + 2 ] &amp;&amp; dy + 1 &lt; height ) {
							col_output[ 4 * (dy + 1) + i ] +=
									col_source[ y * source-&gt;width ].v[i] * lookup_y[ 3 * y + 2 ];
						}
					}
				}

				for( y = 0; y &lt; height; y++ ) {
					for( i = 0; i &lt; 4; i++ )
						(scaled_y-&gt;data + y * width + x)-&gt;v[i] =
							(unsigned char)(col_output[ 4 * y + i ] &gt;&gt; 8);
				}

			}

			free( col_output );
			free( lookup_y );
		}
	}

	if( scaled_y ) {
		if( scaled_x )
			image_destroy( scaled_x );

		FV_StopTimer( 0 );
		return scaled_y;
	}

	if( scaled_x &amp;&amp; !scaled_y ) {
		FV_StopTimer( 0 );
		return scaled_x;
	}

	return NULL;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1380624</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380624</guid><dc:creator><![CDATA[-Foo-]]></dc:creator><pubDate>Mon, 08 Oct 2007 16:28:47 GMT</pubDate></item><item><title><![CDATA[Reply to Bilder verkleinern on Mon, 08 Oct 2007 18:27:52 GMT]]></title><description><![CDATA[<p>auf was für nen lahmen möhre arbeitest du denn da? ^^ soll die skalierung interpolieren oder reichts, wenn einfach überflüssige pixel rausgeschmissen werden?<br />
und nen genereller tipp: für arbeiten auf den pixeln ist es häufig effizienter, wenn die pixeldaten in nem eindimensionalen array vorliegen, damit rumgerechnet wird und erst ganz zum schluss das ergebnis wieder in ein high level objekt transformiert wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380726</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380726</guid><dc:creator><![CDATA[thordk]]></dc:creator><pubDate>Mon, 08 Oct 2007 18:27:52 GMT</pubDate></item><item><title><![CDATA[Reply to Bilder verkleinern on Mon, 08 Oct 2007 18:44:12 GMT]]></title><description><![CDATA[<p>Also ich dachte mir interpolieren ist schon schön, sonnst wär das bestimmt schneller, aber ich kann mir vorstellen, dass es dann irgendwann ziemlich kacke ausschaut.<br />
Meine lahme Krücke ist ein Pentium 4 mit 3.06Ghz (das war der erste mit HT, soweit ich mich erinnere =)... gut bringt mir jetzt hier wenig... )<br />
Naja das mit dem eindimensionalen Array kann ich ja nochmal drauf übertragen, vllt bringt das ja tatsächlich noch was, aber ich arbeite ja im Prinzip schon mit einem eindimensionalen Array, nur dass ich das nach jeder Zeile wieder zurück schreib statt am Ende... Dürfte im Prinzip doch nciht viel unterschied machen?<br />
Gruß, Olli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380745</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380745</guid><dc:creator><![CDATA[-Foo-]]></dc:creator><pubDate>Mon, 08 Oct 2007 18:44:12 GMT</pubDate></item><item><title><![CDATA[Reply to Bilder verkleinern on Mon, 08 Oct 2007 22:38:50 GMT]]></title><description><![CDATA[<p>hab grad mal ne variante zusammengeklebt, die mit unsigned chars auf eindimensional arrays arbeitet aber haufenweise float multiplikationen verwendet. reine skalierungen ohne sonstigen schnickschnack purzeln da ca. 125 pro sekunde raus. (für die interpolation hab ich ne simple 3x3 faltung verwendet)<br />
glaub mit ner einfachen straight forward lösung ist man doch schneller ^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380904</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380904</guid><dc:creator><![CDATA[thordk]]></dc:creator><pubDate>Mon, 08 Oct 2007 22:38:50 GMT</pubDate></item><item><title><![CDATA[Reply to Bilder verkleinern on Tue, 09 Oct 2007 04:39:20 GMT]]></title><description><![CDATA[<p>da sieht man es mal wieder. es kommt auf den algorithmus an und nicht drauf ein paar &quot;perfomancetricks&quot; zu verwenden. google mal nach &quot;faltung&quot; und &quot;separierbare filter&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380929</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380929</guid><dc:creator><![CDATA[tja]]></dc:creator><pubDate>Tue, 09 Oct 2007 04:39:20 GMT</pubDate></item><item><title><![CDATA[Reply to Bilder verkleinern on Tue, 09 Oct 2007 06:05:23 GMT]]></title><description><![CDATA[<p>hab das ding mal hier hingepackt <a href="http://nopaste.info/0c0318a76a.html" rel="nofollow">http://nopaste.info/0c0318a76a.html</a><br />
ewig kein reines c mehr gecodet, übernehm keine verantwortung für standard konformität <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
soll eher als beispiel gelten, ist eigentlich kein bisschen optimiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1380952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1380952</guid><dc:creator><![CDATA[thordk]]></dc:creator><pubDate>Tue, 09 Oct 2007 06:05:23 GMT</pubDate></item></channel></rss>