Canvas größe ändern

Mal mit math.round probiert oder math.ceil? Hatte aenhnliche probleme
weiss aber nicht mehr obs am ende am selben lag wie bei dir


ah mir faellt noch ein es koennte am filter liegen.
Gibt verschiedene filter, einer skaliert die pixel korrekt,
Der andere benutzt sowas wie antialiasing, wobei die raender pixel aus nachbar
pixeln berechnet werden. Kann sein dass es daher kommt.
Filter waren entweder beim paint oder graphics objekt bin
mir grade nicht ganz sicher.
 
Zuletzt bearbeitet:
wenn du auf die bildschirm maße skalieren willst hol sie dir mit getwidth() und getHeight()


ansonsten benutz einen skalierungsfaktor der beschreibt mit welchem faktor man seine ursprungsdimensionen multiplizieren muss um auf die gewünschte größe zu kommen z.B. von 400 auf 800 px ist der faktor 2 dass auf die höhe und breite angewandt
voila


bei rundungsfehler von float auf int zum beispiel kann höchstens ein pixel schief gehen und nciht gleich so viele(vorausgesetzt du machst nciht schon vorher rundungen)


wenn du ein float in ein int übergehen lassen willst und er so wie im normalen leben runden soll und nciht (alle stellen nach dem komma weg...was leichter ist für den computer der braucht dann nur diese bits nciht zu übernehmen) einfach den wert vorher mit 0.5 addieren so rundet ab x.5 auf statt runter für positive x bei negativen x natürlich - 0.5

Der ursprüngliche Beitrag von 20:26 Uhr wurde um 20:33 Uhr ergänzt:

und bei einem einhalten des apect ratios aus der ursprungsbildquelle heißt ein bild von einem kreis soll auch ein kreis sein

hast du keine chance dass es auf jeden bildschirm richtig angezeigt wird ohne balken

dafür gibt es zu viele unterschiedliche bildschirm auflösungen(Beispiel schwarze balken bei filmen im fernsehen die im breitbild format gedreht wurden mal dünner mal dicker je nach auflösung des tvs)
 
hey ich hab ncoh ein vorschlag der dir zu gute kommen sollte:

mit dem surfaceholder deiner surfaceview kannst du bestimmen wie groß der buffer sein wird auf den du deine operationen malen willst:

surfaceHolder.setFixedSize(newWidth,newHeight);

dadurch wird dein canvas den du lockst die neuen maße haben und zwar immer...die hardware macht für dich die sklaierungsaufgabe....heißt du kannst selbst bestimmen wie groß deine zeichenfläche ist und das handy wird dementsprechend hoch oder runterskalieren.

beachte aber wenn du toucheingaben machst dann sind die positionen der objekte jetzt dementsprechend verschoben du sieht ja nur das sklaierte bild aber dort sind ja deine objekte nciht mehr ...


ich hab das zum beispiel so gelöst:

PHP:
int surfaceWidth=500,surfaceHeight=500,screenWidth=getWidth(),screenHeight=getHeight;

float scaleFactorWidth=screenWidth/surfaceWidth;
float scaleFactorHeight=screenHeight/surfaceHeight;

sHolder.setFixedSize(surfaceWidth,surfaceHeight);

float touchX,touchY,posX=surfaceWidth/2f,posYsurfaceHeight/2f,objWidth=surfaceWidth/20f,objHeight=surfaceWidth/20f;
iin der ontouch methode:

PHP:
if(Math.abs(touchX-posX*scaleFactorWidth)<=objWidth*scaleFactorWidth/2&&Math.abs(touchY-posY*scaleFactorHeight)<=objHeight*scaleFactorHeight/2)
{
    objectTouched=true;
}

etwas wenig code aber sind ja nur die wichtigsten stellen

ich habe ein objekt welches quadratisch ist in die mitte der surface auf die ich malen werde platziert bei 250,250 es wird aber später durch skalierung der hardware auf die mitte des screen projiziert also muss ich vor jeder abfrage einer position meine faktoren mit dem das object skaliert wurde multiplizieren


Vorteil:
-du kannst dich auf einezeichenfläche konzentrieren
-das zeichnen geht viel schneller da deine zeichenoperationen weniger pixel beeinflussen(das ist von vorteil gerade auf 2560x1440 px screens)
-deine bitmaps brauchen nciht mehr so groß sein du läufst weniger gefahr eine OOM zu triggern
-es spart cpu zeit,schont den akku dadurch und verbraucht weniger resourcen

Nachteil:
-Bildqualität nimmt ab
 
Moin Leute,
ich habe eine Ausbildung angefangen, als FiAE. Nun möchte mein Unternehmen, dass ich ein Programm schreibe, das eine digitale Unterschrift erzeugt.
Soweit sogut. Ich habe mich daraufhin schlau gemacht und ein passenden Quellcode gefunden, mit dem ich eine Bitmap und eine Canvas habe, die weiß sind und der Benutzer schwarz schreiben kann. Nun möchte ich die Größe der Canvas ändern, da die Unterschrift nur für das vorgesehene Unterschriftenfeld wirksam sein soll, denn man soll die Quittung bzw. dass was man unterschreibt sehen können. Durch die Beschreibung hier konnte ich nix mitnehmen, da dass alles noch sehr neu für mich ist. Deshalb die Frage, wie ich die Canvas von der Größe her ändern kann?
 
Zuletzt bearbeitet:
Hast du einen Link zum Quellcode?
 
Ich kann dir meinen schicken :)
Code:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Environment;

import android.view.Display;
import android.view.MotionEvent;
import android.view.View;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;



public class draw_view extends View {

    private Paint paint = new Paint();
    private float lastX, lastY;
    private boolean drawing = false;

    private Bitmap bitmap;
    private Canvas canvas;


    public draw_view(Context context) {
        super(context);
        setFocusable(true);
        paint.setAntiAlias(true);
        paint.setARGB(0, 0, 0, 0);
        //paint.setColor(Color.TRANSPARENT);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {


        bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);//ARGB_8888 für transparenz
        canvas = new Canvas(bitmap);

        if (bitmap != null) {
           // Rect rectangle = new Rect(0,0,600,500);// Größenänderung der sichtbaren Box, zeigt bildschirm verkleinert an.
           // canvas.drawBitmap(bitmap, null, rectangle, null);
            Matrix matrix = new Matrix();
            matrix.preTranslate(50,50);
            matrix.preScale(0.5f,0.5f);
            canvas.drawBitmap(bitmap, matrix, null);

        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        if (bitmap != null) {
           // Rect rectangle = new Rect(0,0,600,500);// Größenänderung der sichtbaren Box, zeigt bildschirm verkleinert an.
            //canvas.drawBitmap(bitmap, null, rectangle, null);
            Matrix matrix = new Matrix();
            matrix.preTranslate(50,50);
            matrix.preScale(0.5f,0.5f);
            canvas.drawBitmap(bitmap, matrix, null);


        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            drawPoint(event.getX(), event.getY(), event.getPressure());
            return true;
        }
        else if (event.getAction() == MotionEvent.ACTION_UP) {
            drawing = false;
            return true;
        }
        else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            drawing = true;
            drawPoint(event.getX(), event.getY(), event.getPressure());
            return true;
        }

        return false;
    }

    private void drawPoint(float x, float y, float pressure) {
        if (bitmap != null) {
            //int pressureLevel = (int)(pressure * 255);
            //paint.setARGB(pressureLevel, 255, 255, 255);
            paint.setARGB(255,0, 0, 0);//Farbe des Stiftes
            if (drawing) {
                canvas.drawLine(lastX, lastY, x, y, paint);
            }
            else {
                canvas.drawPoint(x, y, paint);
            }

            lastX = x;
            lastY = y;

            invalidate();
        }
    }

    public void clearBitmap() {
        if (canvas != null) {
            paint.setARGB(0xff, 0, 0, 0);
            canvas.drawPaint(paint);
            invalidate();
        }
    }

    public void saveBitmap() {
        if (bitmap != null) {
            try {
                String path = Environment.getExternalStorageDirectory() + "/unterschrift/signatures";
                File dir = new File(path);
                if (!dir.exists() || !dir.isDirectory()) {
                    dir.mkdirs();
                }
                File file = new File(dir.getAbsolutePath() + "/signature.png");
                FileOutputStream fos;
                fos = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.close();
            }
            catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            catch (IOException io) {
                io.printStackTrace();
            }
        }
    }

    public void loadBitmap() {
        String path = Environment.getExternalStorageDirectory() + "/unterschrift/signatures/signature.png";
        Bitmap bmp = BitmapFactory.decodeFile(path);
        if (bmp != null) {
            if (canvas != null) {
                canvas.drawBitmap(bmp, 0, 0, null);
            }
            invalidate();
        }
    }
}


Code:
import android.annotation.TargetApi;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class Unterschrift extends Activity {


    private static final int MENU_CLEAR = Menu.FIRST;
    private static final int MENU_SAVE = Menu.FIRST+1;
    private static final int MENU_LOAD = Menu.FIRST+2;

    private draw_view drawView = null;


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        drawView = new draw_view(this);
        drawView.setBackgroundColor(Color.BLUE);
        setContentView(drawView);
        drawView.setX(100);
        drawView.setY(100);
        drawView.requestFocus();
    }

    @Override public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, MENU_CLEAR, 0, "Clear");
        menu.add(0, MENU_SAVE, 0, "Save");
        menu.add(0, MENU_LOAD, 0, "Load");
        return super.onCreateOptionsMenu(menu);
    }

    @Override public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_CLEAR:
                drawView.clearBitmap();
                return true;
            case MENU_SAVE:
                drawView.saveBitmap();
                return true;
            case MENU_LOAD:
                drawView.loadBitmap();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

Meine Main Activity ist die eine Blank Activity, bei der ich auf den Button runten rechts drücke zund auf die View komme, in der ich zeichnen kann.
[doublepost=1447920844,1447920742][/doublepost]Die Geschichte mit der Matrix habe ich rausgenommen.
 
Aha ok.

Nenne bitte dein globales Canvas objekt "canvas" anders. Es wird in onDraw() vom lokalen Canvas objekt mit demselben Namen überdeckt.

In deinem Fall möchtest du die Größe des Bitmaps "bitmap" ändern. das Canvas objekt "canvas"(der globale Member) malt nur darauf herum.

Zur Zeit übergibst du dem Bitmap die Breite "w" und die Höhe "h", die beim Aufruf von onSizeChanged () als Parameter übergeben werden, der Methode createBitmap() als Breiten und Höhenangaben für das neue Bitmap das erstellt werden soll.

Du brauchst nur deine gewünschte Höhe und Breite beim erstellen des Bitmaps mittels createBitmap() nach deinem Wunsch anzugeben...
 
  • Danke
Reaktionen: tzabbi
Sehr gut funktioniert dankeschön :)
jetzt die nächste Frage, wie bekomme ich es hin, dass die Canvas durchsichtig wird, da die Canvas, ja nach wie vor den ganzen Bildschirm überzieht? Zumindest ist bei mir noch ein weißer Hintergrund zu sehen.
 
Du meinst auch hier wieder das Bitmap durchsichtig bekommen?

Falls ja:
Mit dem Canvas Objekt malst du ja direkt auf das Bitmap das du erstellst.


Du musst einfach nur das Bitmap welches du bearbeitet hast mit Hilfe des Canvas Objekts dann mit Hilfe eines Paint Objektes malen und den Alphawert des Paint Objektes manipulieren

Dafür gibt es die Methode Paint.setAlpha ().Dann malst du mit dem Paint Objekt dein Bitmap.

Das kommt da hin wo du zur Zeit nur "null" übergibst als dritten Parameter also in die drawBitmap() Methode:

Java:
canvas.drawBitmap(bitmap, matrix, paint);//paint=new Paint();paint.setAlpha(/*0-255*/);

Sorry ist noch etwas Früh deswegen kann es sein das manche Aussagen etwas zusammenhanglos oder ungeordnet rüberkommen :)
 
Okay, ich verstehe anscheinend nicht, was Canvas, Bitmap, View, Activity ist.
Nur zum Verständnis: Die Activity ist meine Grundlage(z.B schreibtisch), auf der ich eine View(z.B Blatt Papier) habe, darauf ist die Bitmap(z.B Kästchen was ich ausmale), die mir ermöglicht mit der Canvas(Striche im Kästchen) darauf zu malen?
Könntest du mir bitte noch schreiben, für was die 3 Parameter stehen also (bitmap, matric, paint)?
was füge ich in die () bei paint.setAlpha()?
[doublepost=1447926778,1447925748][/doublepost]Habe ich das paint nicht schon bei
Code:
public class draw_view extends View {

    private Paint paint = new Paint();

definiert?
[doublepost=1447927069][/doublepost]Wenn ich auf meinem Bildschirm oben links schreibe wird mir das angezeigt, wenn ich auf der Bitmap schreibe, dann kommt keine Eingabe(Striche), muss ich da die Canvas verschieben?
 
JA male mit dem PAint dein Bitmp dann. Du machst ja schon paint.setARGB(0,0,0,0);

Ändere das mal in paint.setARGB(125,0,0,0); wobei die 125 ein int wert ist der die opacity angibt 255 ist voll sichtbar und 0 ist unsichtbar...

Was die Enzelnen MEthoden machen kannst du dir in der Android Dokumentation anschauen einfach nach Android Paint googlen und die Doku angucken wofür die MEthoden stehen und was sie machen...
[doublepost=1447928298,1447927861][/doublepost]mit einem Canvas malst du etwas auf eine Zeichenfläche. Das(die Zeichenfläche) kann ein ScreenBuffer sein oder ein Bitmap oder der Hintergrund einer View...

Bitmaps kannst du Googeln was das ist. Quasi eine Bilddatei wenn du es so willst :D
 
Jetzt habe ich einen komplett weißen Bildschirm. Allerdings müsste doch dann meine Activity darunter sein oder? es ist eine Standard Activity(laut meiner .xml Datei.
Code:
 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paintdurch = new Paint();
        paintdurch.setAlpha(125);


        if (bitmap != null) {

            canvas.drawBitmap(bitmap, 93 ,220, paintdurch); // 93 = Position der X-Achse und 220 = Position der Y-Achse, von oben links aus gesehen

der Codeauszug reagiert auf die Striche, die ich mache.
 
Eine leere Activity ohne Inhalt wird eigentlich einen schwarzen Bildschirm rendern. Du musst ihn mit Views füllen vllt wäre ein Bild hilfreich wie du es dir genau vorstellst wie das Ganz aussehen sollte. Nur um mal ne Vorstellung zu bekommen was du erreichen willst.
Also was soll wo sein was soll Hitnergrund sein etc.pp.

Hast du das Layout denn mit dem eingebauten Editor erstellt eigenltich?
 
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
        android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
            android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton android:id="@+id/fab"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

Meine Unterschrift.xml
Ich weiß ganz genau was der Hintergrund sein soll: eine Quittung einer Lastschrift. Dazu noch ein Button mit einem Drucker-Symbol.
meine Draw_View.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:fitsSystemWindows="true"
    tools:context="de.metric.tza.elektrischeunterschrift.draw_view">

    <android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
        android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
            android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_draw_view" />
    <RelativeLayout
        android:id ="@+id/relLay"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

    </RelativeLayout>

    <android.support.design.widget.FloatingActionButton android:id="@+id/fab"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>



Mein Programm läuft so ab, dass es startet in die Main-Activity läuft dort der Standard-Knopf(von der Blank-Activity) betätigt werdern muss, um dann auf meine schreib Activity zu laufen
[doublepost=1447929246,1447929168][/doublepost]der obere Code ist meine Unterschrift.xml
[doublepost=1447929837][/doublepost]Die Bitmap erstellt ja praktisch ein Bild. Demzufoge müsste sie ja garnicht tansparent sein, wenn man diese nur so verkleinert, wie man sie braucht. Verkleinert haben wir sie ja schon. was liegt dann noch so groß als weißer Hintergrund dahinter?
[doublepost=1447929956][/doublepost]Das müsste die drawView sein, also die Hintergrundfarbe, habe Sie gerade mal geändert, kann man von der View die Größe ändern?
 

Ähnliche Themen

D
Antworten
14
Aufrufe
1.794
chrs267
chrs267
C
  • Chicken Wing
Antworten
4
Aufrufe
898
Chicken Wing
C
Vapeilas91
  • Vapeilas91
Antworten
3
Aufrufe
733
swa00
swa00
Zurück
Oben Unten